The company needs to cooperate with the vending machine to sell cosmetics samples. The main function is that users scan the code to log in the applets, obtain the exchange code, enter the exchange code to take the goods, and the management personnel operate the control interface of the vending machine to set the quantity of goods. Because the vending machine pickup function is controlled by the built-in app, it provides the front end with a pickup SDK, which requires the front end to set up an HTML file to be stored in the corresponding app file. However, since it’s 2021, we don’t want to use the native development interface completely, so the final technical solution is to use an HTML file, call the SDK in the file, introduce the functional page written by Vue through iframe, and use PostMessage to enter the communication.

One, page effect diagram

Ii. Functional realization

1.1 HTML How to call the SDK provided by the built-in APP of the vendor

Function spitGoodsByChannelPosition (row, col) {the console. The log (' position, the row, Col) / / off goods window. WebViewJavascriptBridge. CallHandler (' spitGoodsByChannelPosition '{' row' : parseInt (row), 'col: parseInt(col)} , function(responseData) { // console.log(responseData) } ); } function connectWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { callback(WebViewJavascriptBridge) } else { document.addEventListener( 'WebViewJavascriptBridgeReady' ,function() { callback(WebViewJavascriptBridge) }, false ); } } connectWebViewJavascriptBridge(function(bridge) { bridge.init(function(message, responseCallback) { if (responseCallback) { responseCallback(data); }}); bridge.registerHandler("receiveCommandFromSerialPort", function(data, responseCallback) { appendLog("receiveCommandFromSerialPort: " + data) if (responseCallback) { var responseData = "Javascript Says Right back aka!" ; responseCallback(responseData); }}); Bridge. RegisterHandler ("spitGoodsResult", function(data, responseCallback) { Or other functions... }; }; };Copy the code

1.2HTML using iframe to introduce vUE H5 link address

<div class=" Vending-Machine-Container ">< iframe SRC ="vue H5 link address "id="myframe" frameBorder ="0" width="100%"></iframe> </div>Copy the code

1.3 HTML parent page and VUE H5 child page communicate with each other

Here is a brief introduction to iframe + postMessage cross-domain communication

The Web is built on the basis of same-origin policy. Same-origin policy is the behavior of the browser to protect the local data from being polluted by the data obtained by javascript code. Therefore, the interception is the data received back from the request sent by the client, that is, the request is sent, the server responds, but the browser cannot receive it. So we can use the iframe to realize the different domains request resources from each other.

(1) The parent page passes data to the child page

// Pass code var myFrame = document.getelementById (' myFrame '); / / get the iframe ID myframe. ContentWindow. PostMessage ({code: dataCode. ErrorCode}, '*');Copy the code

(2) The data of the parent page interface from the child page

    window.addEventListener("message", function(event) {                 productCallParams = event.data;          console.log('event', event.data)          if (event.data) {            var row = event.data.position_x;            var col = event.data.position_y;            spitGoodsByChannelPosition(row, col);          }        }, false);
Copy the code

1.4 VUE H5 sub-page (obtain exchange code, background management)

Here the code is omitted, some interaction code that everyone understands…

Focus on the generation of sign. In order to prevent repeated submission, students at the back end require each interface to pass the value of sign generated by the front end!

export function getSign(params, kAppSecret) {  let content;  let Base64 = require('js-base64').Base64;  if (typeof params == "string") {      content = params  } else if (typeof params == "object") {      var arr = [];      for (var i in params) {          arr.push(i + "=" + params[i]);      }      content = arr.join("&")  }  let urlStr = content.split("&").sort().join("&");  let hash = CryptoJS.HmacSHA256(urlStr, kAppSecret)  return Base64.encode(hash)}
Copy the code

In general, it can be divided into:

{"key1":value1, # value must be one of the types of a number, Boolean, float, or string "key2":value2, } secret key XXXX Step 1 Sort the key of JSON data structure according to THE ASCII code from small to large, and concatenate it into a string. Step 2 Run the hMAC SHA256 algorithm on the string, and use the secret key XXXX. Step 3 Encode the abstract obtained in the previous step in Base64, and the calculation is completedCopy the code

Pit: When these encryption packages were introduced here, because the original app provided by the vendor was Android 6.0, it could not recognize the cryptoJS package installed by NPM, so I directly put the code down in the util function. It took some effort.

The above is part of the key difficulties of this function, this is recorded.