Development background
A project with another company, passing parameters natively by custom header parameters, which are received by the front end. \
Hit the pit
Native mass participation
Android’s native method of passing parameters is simple, using the webView.loadURL method, as follows:
Map<String, String> map = new HashMap<String, String>();
map.put("Payment-Token", "*****");
myWebView.loadUrl(myEdit.getText().toString(), map);
Copy the code
2 H5 Receiving parameters
In order to receive the header parameters, jquery is introduced in my big VUE framework, as follows:
let req = new XMLHttpRequest(); req.open('GET', document.location, false); req.send(null); let paymentToken = req.getResponseHeader('payment-token') ? req.getResponseHeader('payment-token') : ''; this.paymentToken = paymentToken; If (paymentToken == ") {this.setshade (' failed to obtain order information '); }Copy the code
You see, how simple. And then I got slapped in the face during the test. The front end said that the parameters were not received, the native said passed, each other deadlocked for an afternoon, and finally use the way to modify UserAgent to pass the parameters
myWebView.getSettings().setUserAgentString("****");
Copy the code
At the meeting today, I felt that this way is not normal, and I still need to pass the header parameter in the previous loadUrl way. Suddenly, the boss of the company woke me up with a word, pure front-end VUE can only receive the header of response.
The point is to request a web page, which includes a request and a response. So, there are two headers that we often talk about, a header for request and a header for Response. That’s the problem. Circle it. The native side sends the request header, and H5 receives the Response header. The company uses the Nginx server. I have done some configuration in it. The logic is to get the header parameter in the request, and then dynamically set it to the header in the response
add_header 'Payment-Token' '$http_payment_token';
Copy the code
For example, PHP can read Request parameters directly through Request->header, while VUE cannot. For example, PHP can read Request parameters directly through Request->header.
Let’s take a look at the following examples of webView usage.
References:
WebView detailed and simple implementation of Android and H5 intermodulation
Case a header
Directly on the demand effect diagram:
Requirements: WebView adds headers, H5 reads headers, and hides the bottom menu bar.
Header data to add: ecr-app: Android
The loadUrl(String URL) method is used most of the time. Let’s look at another loadUrl constructor.
loadUrl(String url, Map<String, String> additionalHttpHeaders)
Copy the code
The additionalHttpHeaders parameter literally means: additionalHttpHeaders. For Android 2.2 (i.e. API 8), WebView added an interface method that allows you to load web pages and send HTTP headers.
Take a look at the specific use:
HashMap<String, String> header = new HashMap<>();
header.put("ECR-APP"."android");
mWebView.loadUrl("http://m.test.366ec.net/Default2c.aspx",header);
Copy the code
Run the effect immediately:
The menu at the bottom of the page has been removed.
Case 2 cookies
Cookies are used to record user login information. Users do not need to log in again the next time they log in to the page.
Let’s look at the requirements:
The login page is displayed all the time. So how to solve the multiple login problem? The WebView transmits the loaded URL to the server via an HTTP request. So the Cookie information will be passed through the header.
Set the cookie code as follows:
private void syncCookieToWebView(String url, List<String> cookies) { CookieSyncManager.createInstance(this); CookieManager cm = CookieManager.getInstance(); cm.setAcceptCookie(true); if (cookies ! = null) { for (String cookie : cookies) { cm.setCookie(url, cookie); // Note the port number and domain name, this way can synchronize all cookies, Including the sessionid}} the if (Build) VERSION) SDK_INT > = Build. VERSION_CODES. LOLLIPOP_MR1) {CookieManager. GetInstance (). The flush (); } else { CookieSyncManager.getInstance().sync(); }}Copy the code
Here is the calling code:
List<String> cookies = new ArrayList<>();
// The type of the key-value pair is joined with an equal sign ("=")
cookies.add("StoreManagerTicket=" + "Encrypted token");// It depends on the background negotiation
syncCookieToWebView("Loaded address", cookies);
Copy the code
CookieManager the Cookie will be deposited in the application/data/data/databases/directory webviewCookiesChromium. Cookies of db database table. Open the web page, the WebView reads the cookie value from the database, puts it in the header of the HTTP request, and passes it to the server.
Let’s run this and see if we can get multiple logins again.
The jump is normal, and multiple logins do not occur.
Case 3: Injecting JS
Have you ever encountered such a scenario in a project? The mobile terminal interacts with H5 to provide data support. For example, adjust the local camera, and upload the pictures to the web page; Call location return address to web page; Call two-dimensional code scanning interface to return scanning results and so on.
As follows, there is a scene where the “scan” icon is displayed on the web page. Click to open the mobile phone scan interface and upload the scan result after the scan is successful. So on the mobile end, there are generally the following methods:
JsOpenScanFunction(String callbackFunction)
Copy the code
The callbackFunction parameter indicates the method called by WebView. load after the scan succeeds and has only one parameter (scan result).
Generally, the front-end H5 will call the method of opening the QR code on the Android mobile terminal like this:
// Callback callback
window.JsInterface.JsOpenScanFunction(callback)
Copy the code
The ios side will call it like this:
window.webkit.messageHandlers.JsOpenScanFunction.postMessage(callback)
Copy the code
On the H5 side, it will be done in steps, which will no doubt increase the workload of the developers. How would the H5 side developers feel if there were many places to interact? And later maintenance is also a very tedious thing, there is no better plan?
It would not be very fashion if the H5 side could simply call the mobile side methods as if they were local methods.
Then, it is necessary to inject JS code on the Android side and ios side respectively to facilitate the call from the H5 side.
The injection method is as follows:
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (mIsAddJsCode) {/ / true by default
mIsAddJsCode = false;
mWebView.loadUrl("javascript:" + "function JsOpenScanFunction(s) {\n window.JsInterface.JsOpenScanFunction(s); \n}"); }}Copy the code
Insert a js method into the onPageStarted method:
function JsOpenScanFunction(s) {
window.JsInterface.JsOpenScanFunction(s);
}
Copy the code
In this way, H5 only needs to call JsOpenScanFunction(s) method to realize the function of calling QR code scanning on different platforms. From now on, mother has not worried about the problem of multiple calls.
Note: The JsOpenScanFunction(s) method requires a prior agreement between the front end and the mobile end. Reference: blog.csdn.net/u012551350/…