Sending user information to server to track hits / traffic on site This is working pretty well right now:

var p='';
if(typeof parameters!=='undefined'){p='&amp;p='+parameters;}
var t='';
var l='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for(var i=0;i&lt;64;i++){t+=l.charAt(Math.floor(Math.random()*62));}
if(!sessionStorage.t){sessionStorage.t=t;}
if(!localStorage.t){localStorage.t=t;}
var r=new XMLHttpRequest();
r.open('POST','https://example.com/hit',true);
r.setRequestHeader('Content-type','application/x-www-form-urlencoded');
r.send('r='+document.referrer+'&amp;u='+localStorage.t+'&amp;s='+sessionStorage.t+p);


I have two questions.


About 1% of my hits are getting r, the referrer, correctly, while u and s are NULL. u is like a user id to keep track of unique users, and s is a session id to track the user's session. Are these NULL because of lack of web storage support in the user's browser, or is there another explanation?
Are there any other ways to improve this? Do you see any potential problems?


p is for custom parameters that I need for my individual sites. I already ignore requests from user agents that look like bots. I am pretty sure that the 1% is real users.
For one, I wouldn't work with that code. I would prefer working on a verbosely written code. If you want to shrink this piece of code, use a minifier before release. But on development, work on the full, verbosely-written code.

That said, variable names could be better. p, u, t, s tell me nothing about what these variables are. Best if you expand the names to ones that mean something.

Also, your variables are in the open, in the global scope. There is a slight chance your code would be clobbered by other code on the page. Wrap it in a closure to avoid collision.

Now for your approach.

XMLHttpRequest which is a bit overkill. It's not cross-browser friendly if you factor in older browsers, and you're using a POST request. If you just want to track hits, a "tracking pixel" is much simpler.

It's the same approach, but instead of XMLHttpRequest, you use an image. You create the object, tack the data as query params, append that image to the page to kick the request. Your server receives the data as a GET request, gathers the data, and have it redirect to a dummy 1x1 image as a response, literally a "pixel".

For your ID logic, you will not have 100% ID'ing with your current approach. Clearing the cache will force your logic to regenerate an ID, a totally different ID from previous sessions. This will disconnect the user from any known previous data, making your data erroneous.

Consider generating a hash from pieces of browser data that almost never change. Examples of which are the browser's name, the OS name, the timezone, the screen resolution, browser settings, and so forth. A good place to start is the browser's navigator object.

The name of the technique is "device fingerprinting". The fun thing about this approach is you never have to store the value. Since the values are always present but never change, generating a hash from the same values will always yield the same value.

;(function(){

  function hashFunction(string){
    // Any will do. See http://stackoverflow.com/a/7616484/575527
  }

  var userId = hashFunction([
    navigator.userAgent,
    navigator.oscpu,
    // Add more...
  ].join(''));

  var image = new Image();
  var path = 'https://example.com/hit';
  var params = [
    'r=' + encodeURIComponent(document.referrer),
    'u=' + encodeURIComponent(userId),
  ].join('&amp;');

  document.body.appendChild(image);
  image.src = encodeURI(path + '?' + params);

}());


Taking this approach further, you won't need JavaScript at all. HTTP requests send in non-changing data via headers. There will also be some form of non-changing data via the network, like the request IP address. You can move all of this logic to the back-end, using that data to construct a hash. The page request is sufficient to get the data even.