RE: How long is a Javascript return DNT value good for?

Hi David,

There are several  reasons DNT can change after a browsing context (say for origin adexchange.com) has been initiated:
1) Another browsing context in the same UA has executed a site-specific exception call. This where code running in the context of another origin (usually the top-level browsing context) has executed the storeSiteSpecificTrackingException with "adexchange.com" as one of the targets (or for "site-wide, site-specific" exception by not having an arrayOfDomainStrings property). The adexchange browsing context cannot predict when this can occur. DNT value goes from "1" or null to "0"
2) Another browsing context (again probably the top-level one) has executed removeSiteSpecificTrackingException because the user has revoked their consent on the associated page. This can happen at any time. DNT value goes from "0" to "1" or null (if the general preference had not been set).
3) The Tracking Exception expires because the time specified by the maxAge or expires propery has been exceeded. This can happen at any time. DNT value goes from "0" to "1" or null.
4) The user revokes their consent in the UA UI. This can happen any time. DNT value goes from "0" to "1" or null.
5) The user gives their consent in the UA UI. This can happen any time. DNT value goes from "1" or null to "0".
6) The JS Exception API is not supported by the UA, but the publisher has included a "polyfill" library that simulates the API. This can communicate DNT using the navigator.doNotTrack property to collaborating JS in each subresourse browsing context. Unfortunately this has to be communicated sometime after the subresource browsing context has loaded (in all browsers).

I am NOT saying the value will change within normal synchronous JS execution. This is actually impossible because of the nature of the JS execution environment.

If there is no event then what script in "adexchange.com" has to do is "poll" navigator.doNotTrack by triggering a timer with a callback:

var timer = setInterval(function(){
    var DNT = navigator.doNotTrack;
    if(DNT != lastDNT)
    {
     // do something of great import
                                                                        lastDNT = DNT;
    }
    }, 5000); // poll every 5 seconds

What I am actually saying is:
1) It is always better to wait on an event than having to "poll" with an arbitrary time interval using setInterval or setTimeout
2) If someone wants to implement a polyfill library they need to specify a context, such as an event callback, when navigator.doNotTrack is valid.

Mike


-----Original Message-----
From: David Singer [mailto:singer@mac.com] 
Sent: 02 May 2017 20:11
To: public-tracking@w3.org (public-tracking@w3.org) (public-tracking@w3.org) <public-tracking@w3.org>
Subject: How long is a Javascript return DNT value good for?

This issue came up on the call.  Clearly the DNT value in an HTTP header applies to that transaction (only). But if I call the JS property, which returns the DNT value that would be sent in an HTTP header at that moment, how long can I treat the answer as being true? We’re no longer tied to a transaction.

Mike proposes that the value is only good for as long as you don’t think it has changed, and that we therefore need an event ‘DNT for your origin has changed’ (I am not sure how we distinguish origins). 

I wondered if this was needed, and whether we could set a reasonable temporal scope on the return value. We toyed with ‘while the page remains open’ but this doesn’t answer the question for service workers.

My colleagues point out that
a) the JS property is cheap, it’s simply checking the base value and exceptions, not doing any disk or network traffic
b) the number of places that the code might take a different branch, depending on the answer, is probably quite small
c) it'd be reasonable to require its value to be stable per turn of the runloop. So if you had a function like so:

function thingy() {
   if (navigator.doNotTrack && navigator.doNotTrack.startsWith("1")) {
       a();
   }
   ...
   if (navigator.doNotTrack && navigator.doNotTrack.startsWith("1")) {
       b();
   }
}

The caller of thingy would know (modulo an exception being raised) that either both A and B got called or neither did.



Given these, I think we should adopt (c) and also say roughly “you don’t need to ‘poll’ this value, but you should check it at the points where your Javascript would branch depending on the answer, and not cache previous returns for any significant length of time”.

Dave Singer

singer@mac.com

Received on Tuesday, 2 May 2017 21:37:17 UTC