How to gracefully introduce Shence Web JS SDK

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);
  }
})()

Keywords: SDK script

Added by Belleanme on Sat, 22 Jan 2022 10:03:25 +0200