Concept: A device ID is a fingerprint used to indicate the uniqueness of a user’s device

background

Recently, I am doing the development of user behavior analysis project, which needs to collect the device information of users and use device fingerprint to uniquely represent the operation of devices by users. Web storage is related to the browser. We cannot identify a computer through JS. We can only collect device information by using the browser as the device dimension. A browser on a user’s computer is a device.

The problem

Web variable storage, we immediately think of cookie, sessionStorage, localStorage, but these three storage methods are related to the domain name of access to resources. We can’t create a new device fingerprint every time we visit a website, so we need a way to share device fingerprints across domains

methods

The solution we came up with was to load a static page with a nested iframe, store the device ID in the domain name loaded on the iframe, and get the device ID by sharing variables across domains using the principle of iframe contentWindow communication. The event state is obtained via postMessage, and the encapsulated callback function is called for data processing

implementation

On the SDK collection side, the method is called when the caller initializes

collect.setIframe = function () { var that = this var iframe = document.createElement('iframe') iframe.src = "http://localhost:82/" iframe.style = 'display:none' document.body.appendChild(iframe) iframe.onload = function () { iframe.contentWindow.postMessage('loaded','*'); } // Listen for the message event window.addEventListener("message", Function (){thate.deviceid = event.data.deviceid console.log(' get deviceId ', thate.deviceid) sessionStorage.setItem('PageSessionID',helper.upid()) helper.send(that.getParames(), that.eventUrl); helper.sendDevice(that.getDevice(), that.deviceUrl); }, false); }Copy the code

Scripts nested in static iframe pages

<script> var getDeviceId = function() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); }; var hasCreated = false var _deviceId = '' if(document.cookie){ document.cookie.split('; ').forEach(function(i){ if(i.indexOf('deviceId')>-1){ hasCreated = true _deviceId = i.split('=')[1] } }) } if(! _deviceId && (sessionStorage.getItem('deviceId')||localStorage.getItem('deviceId'))){ hasCreated = true _deviceId = sessionStorage.getItem('deviceId')||localStorage.getItem('deviceId') } if(! hasCreated) { _deviceId = getDeviceId() document.cookie = 'deviceId=' + _deviceId Sessionstorage.setitem ('deviceId',_deviceId) localstorage.setitem ('deviceId',_deviceId)} // Function receiveMessageFromIndex ( event ) { console.log( 'receiveMessageFromIndex', event ) parent.postMessage( {deviceId: _deviceId}, '*'); } // Listen for the message event window.addEventListener("message", receiveMessageFromIndex, false); </script>Copy the code

Further reading

Cross-browser cookie Cross-browser fingerprint identification Browser fingerprint tracing Uses postMessage to solve iframe cross-domain communication problems window.postmessage