Introduction to the

This paper introduces some problems encountered in the process of using Vue to do a single page application in wechat WebView, which is also a relatively common problem. There are highlights at the end of the article, I hope you all come ~

background

Recently, as the Chinese New Year is coming, according to wechat’s past urine nature, there are always various rules and regulations for the review of small programs. Therefore, in order to ensure the normal online progress and version iteration (mainly to get more development time), we plan to use H5 for the activity.

directory

  • Wechat applet jump WebView problem;

  • Wx. config for initialization more elegant writing;

  • Some problems of wechat signature;

  • Some problems encountered by Vue single page application in wechat browser (including wechat Pay);

  • Communication within a single page application;

Wechat applet jump WebView problem

First of all, let’s talk about wechat jump to WebView some things, before we can first take a look at the official document: Web-view · small program

There is nothing to say about normal jumps, but let’s talk about the problems I encountered:

In the small program into WebView, I need to put the small program storage simulation cookie to bring in the past, research a lot of information only get a plan, want to small program to WebView communication can only through the concatenation URL, that is very desperate ah, the cookie how long do you know 😂?

Solution:

In fact, it is relatively simple. We will perform an operation on the cookie before the small program enters the WebView, and md5 the cookie to get a shorter string. The SHORT URL can be obtained through this MD5 splicing, which will reduce a lot of problems.

Note:

  • The address we write in the URL needs to be encodeURIComponent. Avoid Chinese characters in the link, otherwise there will be a white screen when opening the page in iOS.

  • Openid in WebView is different from OpenID in applet, so you’d better use unionID if you need to do user association.

  • The redirected WebView address must be whitelisted in the MP background; otherwise, it cannot be accessed. The domain name must be HTTPS.

  • You can debug the WebView page in the wechat developer tool. JSSDK errors can also be reflected in the debugging tool. Finally, if there is no problem, I will pass it over on the phone by proxy.

Wx. config is an elegant way to write

When a project references the API of JS-SDK, it must first inject configuration information, namely wx.config. The same page (same URL) only needs to be initialized once. The wx.config code is as follows:

Wx. config({debug: false, // Enable the debug mode, the return value of all API calls will be alert in the client, to view the passed parameters, can be opened in the PC, parameter information will be printed in the log, only on the PC. Timestamp:,// Required, generate signature's timestamp nonceStr: ",// Required, generate signature's random string signature: ",// Required, signature jsApiList:" [] // Required, list of JS interfaces to use});Copy the code

You can take a look at the document for specific information. Here is a special reminder that when writing code, it must be written in strict accordance with the requirements in the wechat document, and the case and data type must be consistent with the document. Wechat public platform

These are all words of ‘hard talk’. If you don’t believe me, try ╮(╯_╰)╭



When I write code, I like to write different functions in different methods, and the initialization function only does the initialization, so I feel more comfortable.

  • Js-sdk file must be introduced before all wechat interface calls, and JS interface security domain name must be set.
  • Js-sdk has apis that are called only when triggered by the user. One thing to note is thatwx.configIs an asynchronous operation on the client side, there will be timing problems caused by asynchrony when using the method, so the method is best written inwx.ready,wx.configInformation is successfully verified and executedwx.readyMethods.
  • It’s better to write it habitually when we initialize itwx.errorwithwx.readyAt the same level, so that after the method debugging problems will also be convenient, but also can do error prompts.

Now that the above points are clear, let me give you a more elegant initialization method. The logic is as follows:

First we need to wrap a Promise template around the method, but as MY project uses Jquery, I use the $.deferred () method directly

let defer = $.Deferred();
let ready = defer.promise();
Copy the code

$.deferred () returns a chained utility object method to register multiple callbacks with multiple methods

After writing these two methods, you are almost halfway done.



Following the logic described above,readyIf the initialization succeeds, then the callback isresolve.errorYes initialization failed, callback isreject. And then we usedefer.promise()Accept two states and return a Promise object, and you’ll be happythen().

Note: Deferred.promise () can also take a target argument, in which case the passed target is given the promise method and returned as a result, rather than creating a new object.


// Existing object
var obj = {
    hello: function( name ) {
      alert( "Hello " + name );
    }
  },
  // Create a Deferred
  defer = $.Deferred();
 
// Set object as a promise
defer.promise( obj );
 
// Resolve the deferred
defer.resolve( "John" );
 
// Use the object as a Promise
obj.done(function( name ) {
  obj.hello( name ); // Will alert "Hello John"
}).hello( "Karl" ); // Will alert "Hello Karl"
Copy the code

You can see the introduction of the official website

jQuery API Documentation

Now that we’re all set, let’s start the initial configuration


getWxSign(){
	wx.config({
		debug: false, 
		appId: ,
        	timestamp: ,
		nonceStr: ,
		signature: ,
		jsApiList: [],
	});
	wx.error((err) => {
		defer.reject(err);
	});
	wx.ready(() => {
		defer.resolve();
	});
}
Copy the code

After these two steps are completed, our chain deconstruction is complete, and we can release our own writing. For example, IF I want to obtain the delivery address of wechat, I can write it like this

ready.then(()=>{
	wx.openAddress({
		success: function (res) {},
		fail: function(err) {},
		cancel: function() {}
	});				
});
Copy the code

With this encapsulation, your code will have a big readability boost, or at least look comfortable.

Of course, when using these JSSDK apis, you should remember to add 🔒, otherwise there will be multiple calls, may appear to return several times, of course, I did not try this, you can zuo.

Some problems with wechat signature

As for the problem of invalid wechat signature, I mainly want to mention here. Because this piece of server code is written by another friend, I don’t have much practice. The wechat signature server had better cache the access_token. This can save a lot of unnecessary trouble.

All interface calls need to obtain the Access_token first. The access_token is valid within 2 hours (7200s). After expiration, the access_token needs to be obtained again.

In fact, at the beginning of development, the server-side students have not finished writing this piece of logic, the front-end students can debug, let the server first get configuration information, and then the front-end temporarily write this piece of dead, so that at least two hours is no problem, can improve the efficiency of development.

Update access_token in advance within the validity period of the cache. This allows students on the server side to have the same control over updating access_token separately. In this case, conflicts will occur and invalid signature will be displayed. We need to make full use of the official signature verification tool when confirming such errors

Wechat JS interface signature verification tool

If the signature fails due to the expiration of the token, it is basically prompted after entering the token. At this time, it is necessary to check whether the server side cache time is wrong. At that time, we encountered the problem because the server side time calculation is too much *60…

Of course, there are many problems with signature errors. In the case of ensuring that the signature algorithm has no problems, there may be the following situations:

  • Young people do not know wechat tiger, parameter capitalization is not written according to the official requirements. The two fields nonceStr and TIMESTAMP are highlighted. Timestamp is of type String.

  • Make sure the URL is the complete URL of the page. Location. Href. Split (‘#’)[0]

If the address is: https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign you can URL wrote https://mp.weixin.qq.com/debug/cgi-bin at the next higher levelCopy the code
  • Config is inconsistent with the AppID used to obtain ticket.

  • In addition, if the server does not cache the access_token, we may have problems during debugging by brushing a few times, because during development I feel that it is very possible to brush hundreds or thousands of times.

  • The URL passed by the front end may be processed by encodeURIComponent, and the server needs decode.

  • There is also a URL that the server gets that is inconsistent with the front-end URL. You can copy the link to check this after opening it on the phone.

Vue single page application in wechat browser encountered some problems

Since we used vUE single-page application to complete the activity this time, and the history mode of VUe-router was used for routing, we would encounter a rather annoying problem. I would like to describe the scenario for the specific problem:



Wx. Config is mounted, and invalid signature is reported every time I enter wx.Accidentally found a refresh of the page on the normal. Sometimes the problem address can be used without reporting the signature, but every timeHe gave me the wrong address when he paid.

Finally, AFTER searching the Internet for a long time, I found that in the history mode, the URL used for signature was the SAME as that used when entering the page. In order to confirm the problem, I posted the URL of each page, and it was really the same. Since the problem was confirmed, it was easy to solve.

Solution:

We can first check the type of phone when entering the page. As mentioned above, I encountered the problem on iOS system, but it is not a problem on Android, so there is no need to deal with iOS specifically. As long as the iOS model is recognized, I will change the address, and the code can be referenced as follows:

BeforeRouteEnter (to, from, next) {var isiOS =!! navigator.userAgent.match(/\(i[^;] +; ( U;) ? CPU.+Mac OS X/); //ios terminal if (isiOS && to.path! == location.pathname) { location.assign(to.fullPath) } else { next(); }},Copy the code

Of course, there is more than one solution, in fact, there are many solutions, but it is not very elegant. At that time, my backup plan was either to use the A tag to jump to the page, or after entering the page, you can reload and update the URL. You can choose your own method.

Communication within a single page application

So let me start with the scenario so you can understand the purpose. At the time when doing the project use the function of the whole project is only a piece of communication, at that time, children’s shoes let I don’t want to be in the form page from the server to submit, because the content is not much, let me bring information to the order page settlement when submitted together, this in fact is the communication between the father and son components, but I don’t have enough the need to communicate, to introduce a vuex feeling is too heavy. I’m going to skip this option and use eventBus instead. The code is as follows:

First we need to declare an eventBus js file:

import Vue from 'vue';
var eventBus = new Vue({});
export default eventBus; 
Copy the code

Next you need to pass your value:

import eventBus from 'eventBus/eventBus.js';
let info = {
	a: '',
	b: ''
};
eventBus.$emit('isVal',info);
Copy the code

We add an emit event to the form submission page to send out the content, and then we jump back to the order page.


import eventBus from 'eventBus/eventBus.js';
eventBus.$on('isVal',(data)=>{
        //....
});
Copy the code

Mounted/create/listen on/mounted/once