background
In the past, the company used GrowingIo embedded sites to introduce the Web JS SDK provided by it into each project. However, recently, due to the expiration of the service life and some other considerations, it is ready to use Shence for data embedding and data analysis. Therefore, it is necessary to remove the GrowingIo Web JS SDK introduced into each project and then introduce the Web JS SDK provided by Shence.
programme
If we still adopt the independent introduction of Web JS SDK in each project, we need to sort out the buried point requirements of multiple projects, and then arrange to notify the front-end students of each business group to introduce it in iterative development. Do you find it particularly troublesome that the same web JS SDK needs to be introduced many times, and it also involves cross group collaboration, task allocation, resource arrangement and other issues. More importantly, if another buried point tool is used next time, the repeated things will have to be done again, which will be thankless.
Therefore, we hope that after being introduced in a certain place, the project does not need to be introduced independently. Does this scheme think that it is particularly similar to the idea of gateway service, middleware and interceptor? Can we adopt such ideas to solve the problem? The answer is yes, by injecting the Shence Web JS SDK into the static html script from the front-end routing service request
For some front-end and back-end separated projects, you can operate the static html script in the front-end routing service and inject it into the Shence Web JS SDK implementation, but how to deal with some front-end and back-end separated projects (such as freemaker)? Can we do unified processing in webagent gateway? In fact, it is also feasible. We can judge the response header content type: text / html. If so, operate html to inject Shence Web JS SDK; If not, no processing will be performed. However, in practice, in view of the small number of front and rear end projects that are not separated, we still adopt the first scheme and introduce it independently in the project.
Package Shence Web JS SDK
Shence provides the full buried point function, which is expected to be used and enabled in the project. Therefore, it is necessary to re package and initialize the SDK. Please refer to the following package:
;(function () { /** Judge the environment */ var hostname = window.location.hostname; var serverUrl = 'https://cj.casstime.com/sa?project=default'; if (hostname === 'www.cassmall.com' || hostname === 'h.cassmall.com') { serverUrl = 'https://cj.casstime.com/sa?project=production'; } // Open the full burial point. The full burial point of Web JS SDK includes three events: Web page browsing, web element clicking and web view staying function addShenCeScript() { window.cassSensors = window['sensorsDataAnalytic201505']; // Initialize SDK window.cassSensors.init({ server_url: serverUrl, is_track_single_page: true, // Single page configuration is enabled by default. If there is an anchor design in the page, the configuration needs to be deleted. Otherwise, triggering the anchor will trigger more $pageview events heatmap: { /** * Web Element click ($WebClick) * Whether to turn on the click graph. default means to turn on and automatically collect $WebClick events. You can set 'not'_ 'collect' means close. * By default, the $WebClick element click event is triggered only when the four elements of a input button textarea are clicked */ clickmap: 'default', /** * Viewport stay event ($WebStay) * Whether the touch map is enabled or not. default indicates that it is enabled. The $WebStay event is automatically collected. You can set 'not'_ 'collect' means close. * Web JS SDK version number greater than 1.9.1 is required */ scroll_notice_map: 'default', // Through collect_tags configures whether to enable the full buried point collection of any other element (no collection by default). div can collect up to 3 layers of nesting through configuration. collect_tags: { div: { max_level: 3, // The default is 1, that is, only leaf div is supported. The configurable range is [1, 2, 3]. If it is not configured in this range, it will be treated as 1. }, li: true, span: true, i: true, img: true }, }, }) // Register public properties window.cassSensors.registerPage({ platform_type: 'web', path_name: window.location.pathname, }) /** * Web Page view ($pageview) * After setting, the SDK will automatically collect page browsing events and set the initial source. */ window.cassSensors.quick('autoTrack'); /** Obtain the user login ID. after the user logs in, the developer calls login and passes the user login ID to the SDK. The subsequent distinct of all events on the device_ The ID will become the login ID corresponding to the user.*/ ajax({ url: '/webim/user/jwt_token', type: 'GET', success: function (res) { try { var data = JSON.parse(res); window.cassSensors.login(data.username); } catch (e) { } }, error: function (error) { } }); } var script = document.createElement('script'); script.setAttribute('type', 'text/javascript'); var explorer = window.navigator.userAgent; if (explorer.indexOf('MSIE') >= 0) { // ie script.onreadystatechange = function () { if (this.readyState === 'loaded' || this.readyState === 'complete') { addShenCeScript(); } } } else { // chrome script.onload = function () { addShenCeScript(); } } script.setAttribute( 'src', 'https://mstatic.cassmall.com/assets/sensors/sensorsdata1.19.4.min.js' ); /** Encapsulating ajax requests */ function ajax(params) { params = params || {}; params.data = params.data || {}; // Determine whether it is an ajax request or a JSON request var json = params.jsonp ? jsonp(params) : json(params); // ajax request function json(params) { // The request method is GET by default params.type = (params.type || 'GET').toUpperCase(); // To avoid special characters, the transmitted data must be formatted params.data = formatParams(params.data); var xhr = null; // Instantiate XMLHttpRequest object if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else { // IE6 and below xhr = new ActiveXObjcet('Microsoft.XMLHTTP'); }; // Listen for events. Whenever the readyState value changes, the readystatechange event will be called xhr.onreadystatechange = function () { // The readyState property indicates the current activity stage of the request / response process. 4 is completed and all response data has been received if (xhr.readyState == 4) { var status = xhr.status; // Status: the HTTP status code of the response, and those starting with 2 are successful if (status >= 200 && status < 300) { var response = ''; // Determine the content type of received data var type = xhr.getResponseHeader('Content-type'); if (type.indexOf('xml') !== -1 && xhr.responseXML) { response = xhr.responseXML; //Document object response } else if (type === 'application/json') { response = JSON.parse(xhr.responseText); //JSON response } else { response = xhr.responseText; //String response }; // Successful callback function params.success && params.success(response); } else { params.error && params.error(status); } }; }; // Connecting and transmitting data if (params.type == 'GET') { // Three parameters: request mode, request address (in get mode, the transmission data is added after the address), asynchronous request (synchronous request is rare); xhr.open(params.type, params.url + '?' + params.data, true); xhr.send(null); } else { xhr.open(params.type, params.url, true); //You must set the content type when submitting xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); // Transmit data xhr.send(params.data); } } //Format parameters function formatParams(data) { var arr = []; for (var name in data) { // encodeURIComponent(): used to encode a part of a URI arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name])); }; // Add a random number parameter to prevent caching arr.push('v=' + random()); return arr.join('&'); } // Get random number function random() { return Math.floor(Math.random() * 10000 + 500); } } if (!window.cassSensors) { document.getElementsByTagName('head')[0].appendChild(script); } })()