0 foreword


Recently the focus of work has been in the small program, but also developed several small program, small program development process and related technology is relatively familiar, in the development process also summed up some experience, understand some small program documents do not have things, stepped on some pits. So I want to write an article to record, and take this small program development related knowledge to comb, convenient for future reference, but also as a phased summary of their own work. At the same time, I also hope to make more friends through this article, communicate more, learn from each other and make progress together. In addition, if the article is wrong, but also hope to point out and give advice.

1 basic knowledge and concepts of wechat applets


Micro channel small program development, entry is very simple, as long as you can see the official document small program simple tutorial. How to apply for a small program account, how to develop your first small program, how to publish, this series of hello World operation official documents are hand to hand instruction. Each step of small program development, the ability to provide documentation, I think, do small program development, something is all right to see the document, because small program update relatively fast, at the same time some small ability we may miss, so look at the document.

1.1 Brief description of directory structure and app.json


The file directory structure is flexible

Let’s start by looking at the file directory structure of a small program project

Json files are optional and can be deleted, except that app.json must be in the root directory. And page files can be placed where they are, as long as they are configured in Pages in app.json. Very flexible, so to speak. You can also put multiple pages in the same folder (I’m sure you won’t do that, so why kill yourself).

Here is a brief introduction to each file:

Global configuration file app.json

The most important file for a small program project is app.json, which is the identifier that the development tool uses to identify whether a folder is a small program project. When creating a project using the Developer Tool, if the empty folder is selected, it will create a new project. If it’s a folder with files, it looks to see if there’s an app. Jon file in that folder, and if there is, it thinks it’s a small program project and opens it, and if there isn’t an app.json file in that folder, it says you can’t create the project.

App. json must be placed in the root of the project, which is the global configuration file for the applet project. After the small program code package is ready and started (the whole process from the user clicking to open the small program to the destruction of the small program will be described in detail below), the app.json file will be read first to conduct the preliminary test of the small program, such as initializing the outer frame style of the entire small program and obtaining the address of the home page.

In fact, the small program is a container provided by wechat, each page is loaded in this container to run the destruction

Here are the global configuration options for applets:

Note:

  • The key of all configuration items must be enclosed in double quotation marks, and the value of a string must be enclosed in double quotation marks. Single quotation marks are not supported
  • Because applets iterate very quickly and the base library version is updated very quickly, the following is the latest version of library 2.4.0 as of now
  • pages

    "pages": [
        "pages/index/index"."pages/log/log"
    ]
Copy the code

In app.json, the Pages option is mandatory. This configuration item registers the addresses of all pages of the applet, each of which is the path to the page + the file name. The configured string is essentially the WXML path for each page, with the.wxml suffix removed. Json,.js,.wxml, and.wxss files in the path are automatically integrated by the framework. Json,. Js, and. WXSS files must have the same file names as those of. WXML; otherwise, the files do not take effect. So a page must have at least a.wxml file.

Conclusion:

  • The. Json,. Js, and. WXSS files on the page must have the same name as the. WXML file; otherwise, the files do not take effect
  • Each page must be registered under pages, not registered pages, if you do not visit, compile can pass, once you try to access the page will report an error
  • You can quickly create a page by adding an option under Pages, and the development tool automatically generates the corresponding file
  • window

  "window": {"enablePullDownRefresh": ture,
    "navigationStyle": "custom"
  }
Copy the code

This configuration item is used to configure the global appearance style of applets. For details, see the documentation. Here are two more practical ones

// Remove the default navigation bar, easy to achieve full screen"navigationStyle": "custom"// Enable the built-in pull-down refresh to reduce your own writing styles"enablePullDownRefresh": ture, 
Copy the code
  • tabBar

This option allows us to easily implement the navigation bar TAB effect, but the drawback is that the jump is very low. That is, each TAB can only jump to the current applet page, different to jump to other applet. If you need to jump to other applets, you need to wrap a component yourself.

  • networkTimeout

This is the network request timeout period. You can set the timeout period for different types of requests, such as Wx. request and wx.uploadFile. In fact, many times we ignore this option, small application default is 60 s timeout, but we should manually set a lower value, interface because we are generally finish the request in 10 s (if more than 10 s, so when you are optimized), so if there is something wrong with the network or server, so will allow the user to 60 s, such as the last or failure, This is not user friendly, so it’s better to tell the user in advance that something is wrong now and please try again later.

Some time ago, due to a small problem in the company’s server gateway, some requests could not be connected, resulting in a large number of connection timeout. Through the error information collection plug-in added earlier (this is a performance optimization, which will be discussed below), I see that many interfaces return time-out 60s. Making users wait 60 seconds and still fail is not friendly. Therefore, it is better to set the timeout period to 15s-30s.

  • debug

Whether to enable the debug function. After this function is enabled, you can view more debugging information to locate problems. You can enable this function during development

  • functionalPages

Wx. login and Wx. requestPayment cannot be used in the plug-in. If you need to obtain user information and make payment, you must also use the functions provided by the plug-in. This option must be set to true when plugins in your applet are enabled

Small program plug-in must be mounted in a wechat small program, a small program can only open one plug-in. This option must be set to true when plugins are enabled for your applet

  • plugins

    "plugins": {
        "myPlugin": {
            "version": "1.0.0"."provider": "wxidxxxxxxxxxxxxxxxx"}}Copy the code

This is where applets that use plug-ins must be declared. A small program opened by itself cannot be applied in itself

  • navigateToMiniProgramAppIdList

    "navigateToMiniProgramAppIdList": [
        "wxe5f52902cf4de896"
    ]
Copy the code

Before the small program between as long as it is associated with the public number can jump to each other, now wechat has made a limit, to this configuration here need to jump to the small program, the upper limit is 10, but also must write dead, do not support configuration. So when the small program to jump to other small programs, must match this, otherwise can not jump.

  • usingComponents

  "usingComponents": {
    "hello-component": "plugin://myPlugin/hello-component"
  }
Copy the code

You must declare this before using custom components or components provided by plug-ins

1.2 Small program startup and life cycle


Let’s talk about the process from the user click open to destroy the applet. To make it clearer, I drew a flow chart:

There are two cases of small program start, one is “cold start”, one is “hot start”. If the user has opened a small program, and then in a certain period of time to open the small program again, at this time no need to restart, just switch to the background state of the small program to the foreground, this process is hot start; Cold start refers to the situation that the user opens it for the first time or the mini program is actively destroyed by wechat and opened again. In this case, the mini program needs to be reloaded and started.

The above flow chart covers everything, but the text is limited, so let’s talk about a few more points.

  1. The applets will first detect whether there is a local code package, then use the local code package to start the applets, and then asynchronously detect the remote version. This is the offline capability of the applet, which is an advantage over the H5, speeding up the start of the applet.
  2. When there is a local applets package, the remote end is asynchronously asked if it has the latest version. Some are downloaded locally, but this startup will use the previous code. So when we release the latest version, users need to cold boot twice before they can use the latest version. If you want the user to be able to use the latest version with a cold boot, you can use the version update API provided by the applet to update. Add the following code to the app.js onShow function to prompt the user to update the applet every time it is updated. However, every time this prompt updates, to a certain extent, affect the user experience. If combined with the back-end configuration, each time you come in to read the configuration, you can implement whether to update the version according to need, such as the user must update to use, then use the forced update. For some small versions, this forced update is not necessary.
    if (wx.canIUse('getUpdateManager')) {
        // Check if there is a version update
        var updateManager = wx.getUpdateManager()
        updateManager.onCheckForUpdate(function (res) {
            // After requesting the new version information callback, there is an update
            if (res.hasUpdate) {
                wx.showLoading({
                    title: 'New version detected',
                })
            }
        })
        updateManager.onUpdateReady(function () {
            wx.hideLoading();
            wx.showModal({
                title: 'Update Prompt'.content: 'The new version is ready. Do you want to restart the application? '.success: function (res) {
                    if (res.confirm) {
                        // Clear the local cache
                        try {
                            wx.clearStorageSync()
                        } catch (e) {
                            // Do something when catch error
                        }
                        // The new version has been downloaded. Call applyUpdate to apply the new version and restart
                        updateManager.applyUpdate()
                    }
                }
            })
        })
        updateManager.onUpdateFailed(function () {
            // Failed to download the new version
            console.log('New version download failed'); })}Copy the code

1.3 Development Tools


When it comes to small program development tools, there is no one that satisfies developers, at least not me, hahaha! Wechat developer tools provided by wechat. Except for the compiler, everything is ok. However, due to the development tools, ios, Android three platforms running small program kernel is different. So sometimes there will be problems with the development tools and problems with the real machine, especially with styles. Most of these problems can be solved by setting up style completion when uploading code in the development tools. In addition, wechat developer tools provide real machine debugging function, which is very convenient for real machine debugging

There is also the ability to customize compilation conditions

1.4 test – review – launch stuff


Server domain name Request The legitimate domain name can be changed only five times a month. So you should not add a new domain every time you request one. In the development stage, check the legitimate domain name on the wechat developer tool. Debugging mode needs to be enabled on the real phone, so you can request any domain name or even IP address without configuring the legitimate domain name. After the development is completed, configure all legitimate domain names once again, cancel the verification of legitimate domain names on the wechat developer tool, close the debugging mode on the real machine, and then start the test.

Use the Experience + Online environment interface, this is exactly the same as the online environment, so use the Experience + online environment to go through before release. If it’s okay, it’ll be okay when it’s released.

Small program TWO-DIMENSIONAL code as long as the online version of the call generation small program two-dimensional code interface can be successfully returned two-dimensional code. And two-dimensional code recognition is online version, so has not released the small program is unable to generate two-dimensional code.

The online version has a version rollback function, there is a pit, is the version rollback, the returned version needs to review before release

There are experience version can set the specified path and parameters, so it is very convenient to test

2 Focus on several components


Next, let’s talk about a few components that are more frequently used and powerful, but have more pits

2.1 the web – the view


Web-view makes it possible to jump between small programs and H5 web pages. You can make the H5 page run within the applet by placing it in a Web-view. You can also go back to the small program page on the H5 page. It’s a great convenience, but it’s also not very comfortable to use because of the limitations of Web-View.

  1. The H5 page to be opened must be configured in the background service page, which also includes service verification. In addition, the H5 page must be HTTPS; otherwise, the page cannot be opened
  2. There is no way to set up sharing on a page in Web-view, if sharing is needed, such as jumping back to the applet native page
  3. Small program and web-view H5 communication problem. Applets are passed to the Web-view, and insensitive information can be passed through the page URL. If it is sensitive information such as user token, the server can be redirected. For example, the server can be requested to write sensitive information in the cookie and then redirected to our H5 page. H5 pages can then take sensitive data in cookies, or http-only, when sending requests.
  4. The page is reloaded every time the SRC value in the Web-view changes. Therefore, when a SRC concatenation parameter is used, it is necessary to assign a value to a variable to concatenate and then setData to the SRC of the web-view to prevent repeated page refresh
  5. Starting from wechat client version 6.7.2,navigationStyle: customInvalid for component. This means that when using web-View, the built-in navigation bar cannot be removed.
  6. Because the navigation bar couldn’t be removed, there was a giant crater. Full screen effect problem. If you want to achieve full screen H5 page, you do not swipe, display all content in full screen. Now if you usewidth:100%; height:100%You may notice that a paragraph is missing at the bottom of your page. Above:

By default, the width of the Web-view is the same as the width and height of the screen. And then the H5 page this is the height of 100%, which is the height relative to the Web-view, which is the height of the screen. But the key issue: the H5 page in web-view is rendered from under the navigation bar. This causes the H5 page to overflow the screen and not reach full screen.

The solution

I met this problem in my actual project some time ago. We were going to make an H5 game, which required full screen. At the beginning, I also set the height to 100%. It turned out the bottom piece was missing. My solution is rough, if there is a better solution, welcome to comment and exchange. My solution is to concatenate the width and height parameters on the H5 page URL, which are calculated in the outer layer of the Web-view. H5 page directly reads the width and height of the URL, and dynamically sets the width and height of the page. The page height calculation, as shown above, is obviously screen height minus navigation bar height. It’s the same width, it’s the width of the screen.

But again, there seems to be no way to get the height of the navigation bar. And the height of the navigation bar varies from phone to phone. After comparing the height of the navigation bar and the screen of multiple models. A rule is found that the height of navigation bar is related to the height of screen and the ratio of width to height of screen. So the ratio was calculated based on multiple models. This solved more than 95 percent of the phone’s compatibility issues, with only a few models not fitting very well. To basically achieve the full screen effect. The specific code is as follows:

onLoad (options) {
    // Get screen information synchronously, now use the screen width and height
    var res = wx.getSystemInfoSync();
	if (res) {
		var widHeight = res.screenHeight;
		// For most phones, screen height/screen width = 1.78. The ratio of navigation bar to screen height is 0.875
		var raito = 0.875;
		if (res.screenHeight / res.screenWidth > 1.95) {
		    // For full-screen phones, the ratio is higher
			raito = 0.885;
		} else if (res.screenHeight / res.screenWidth > 1.885) {
			raito = 0.88;
		}
		// Make compatible processing, only wechat version library is higher than 6.7.2, there is a navigation bar to make compatible, otherwise you can directly use the height of 100%. Res. statusBarHeight is the height of the status bar at the top of the phone
		If the wechat version number is greater than 6.7.2, there is a navigation bar
		if (util.compareVersion(res.version, 6.7.2 "") > 0) {
			widHeight = Math.round(widHeight * raito) + (res.statusBarHeight || 0);
		}
		this.setDate({
		    // Add the width and height of the H5 page to the URL, and assign the SRC value to the web-view to load the H5 page
		    webview_src: util.joinParams(h5_src, {
		        "height": widHeight, 
		        "width": res.screenWidth
		    })
		})
	}
}
Copy the code

2.2 scroll – view


When we want to implement an area slide, we can set overflow-y: scroll on the H5 page. But in applets, there is no such property. You need to use the scroll view tag. For detailed operations, you can view the scrollview file.

Anchor location is often used in front-end development. In the H5 page, we will add # after the URL to achieve anchor location effect. But this doesn’t work in applets because the ease of rendering pages in applets is not a browser that can listen for changes in Hash value in real time. But using scroll View, we can achieve anchor point position. The main use of scroll into-vie property concrete implementation we directly on the code

Scroll – into – the view | String | value should be a child element id (id cannot begin with Numbers). You scroll to the element in which direction you can scroll

WXML file

    <! --toView value changes dynamically. When toView is LuckyDraw, it will locate the view with id luckyDraw.
    <scroll-view scroll-y scroll-into-view="{{toView}}" 
    scroll-with-animation = "true" style="height: 100%; white-space:nowrap">
        <view id="top"></view>
        <view id="luckydraw"></view>
        <view id="secskill"></view>
    <scroll-view>
Copy the code

2.3 canvas


The canvas TAB, which is a native component, must be at the top of the screen and cannot be hidden. So if you want to use canvas dynamic generation to share photos. Then you have to make it the same width and height as the screen. Otherwise it will be distorted when exported as a photo. For this reason, generating shared photos should be implemented on the server side, the photos are too distorted.

3 formid collection


Sending a message to the user is very important for a small program, it can call the user back, the derivative effect is very obvious. We can send messages to applet users via template messages, but only if we get the OpenID and FormID. After the user logs in, we can obtain the user OpenID. And as soon as the user clicks, we can get the formid and we can get the formid. So formID is important. We can collect formids in advance and push messages to users when needed. We can wrap the form label in each button, and collect the form ID as long as the user clicks on it.

<form bindsubmit="formSubmit" report-submit='true'> <button formType="submit"> </button> </form>Copy the code

We implement a formID collection system, and in order to minimize redundant code and impact on the business, our design looks like this

  1. Wrap the form tag in the outer layer of the entire page, not every button, so that every button is in the pageformTpye=submitThe formid can be obtained by clicking on the button.
  2. The formID is stored in an array of global variables and is sent once when the applet switches to the background.
  3. For messages that need to be sent in real time, values are not added to the global array and stored directly in page variables.

WXML file

    <! -- Wrap the form tag around the top of the page, instead of wrapping a form tag around each button.
    <form bindsubmit="formSubmit" report-submit='true'>
        <view>The page content</view>
        <view>The page content</view>
        <button  formType="submit">Click on the</button>
        <view>The page content</view>
        <view>
            <button  formType="submit">Click on the</button>
        </view>
    </form>
Copy the code

Page. Js file

    // FormID is added to the global array every time the user clicks
    formSubmit(e) {
        // If you want to send it in real time, do not add it
        if(e.target.dataset.sendMsg){
            formid =  e.detail.formId;
            return;
        }
        app.appData.formIdArr.push(e.detail.formId);
    }
Copy the code

app.js

    onHide: function () {
        // Upload the formid when the applet cuts to the background
        this.submitFormId();
    },
Copy the code

4 Performance optimization


From the user opening the applet to its destruction, we can think about where we can optimize. The first is opening speed. The speed at which miniprograms open directly affects retention. In the background of the small program, there is a loading performance monitoring data under the operation and maintenance center – monitoring alarm. We can see the loading related data such as the total startup time, download time and first rendering consumption of the small program. The opening speed here is actually the total startup time of the small program. It includes the code package download, the first rendering, wechat environment initialization and other steps. At this stage, what can we do to speed up the code package download and reduce the first render time

After the applet is presented to the user, the question of how to improve the user experience and enhance the robustness of the applet is raised. Every program has bugs. We just didn’t find it, even though we did exhaustive testing during the beta phase. However, in the actual production environment, different user environments and different operation paths can trigger some hidden bugs at any time. If the user doesn’t report to us, we can’t know. So it is necessary to add error information collection to our small program, JS script error, meaning that the whole program hangs, unable to respond to user operations. So we should report script errors at runtime. Fix bugs in time to enhance program robustness and provide user experience.

Each program has a large number of front and back end data interactions, which occur through HTTP requests. Therefore, another error information collection is interface error information collection. For those request status code is not 2XX, 3XX, or the request interface is successful, but the data is not expected, we can carry out information collection.

By monitoring the scripts and HTTP requests of the running time of the small program, we can know the running status of our online small program in real time, and find and repair any problems in time, which greatly improves the user experience.

4.1 Make small programs faster


There are two main factors to make small programs fast, code package download and first screen rendering. Let’s look at a statistic:

The previous status applet code size is about 650Kb, this is the download time (although it depends on the user network, but this is the average time for all users) is about 1.3s. But after optimization, the code package is reduced to about 200KB. The download took about 0.6s. So a 500KB reduction in the code package reduces the download time by 0.5s. Again, that’s a pretty striking statistic. Therefore, without affecting the business logic, our applet code package should be as small as possible. So how do you reduce the code package size? Here are a few things to consider

  1. Because when we upload the code to the wechat server, it will compress our code, so the code package downloaded by users is not the size of our development. There is no need to delete blank lines and comments during development. You can see the last upload size in the development tool project details, which is the size that the user ends up using. If you think wechat compression is not good enough, you can use a third-party tool to compress our code and then upload it, and then compare the effect to see if it is smaller. This is not used. If there is a good tool, welcome to recommend.
  2. Prevent static resource files from being stored on our own server or CDN. A small program, the most space is often a picture file. So we can pull it out, and the image file can be retrieved asynchronously, and retrieved after the applet starts. This way, the code package is much smaller.
  3. Use subcontract loading. Applets provide subcontract loading capabilities. If your small program is large, consider subcontracting to load the necessary functionality first. This can greatly reduce the code package size

Next is the first screen rendering. It can be seen from the life cycle of the small program in the figure above that the time when the home page code is loaded and the home page is completed is the white screen time, that is, the first rendering time. During this period of time, the main work of the small program is: loading the home page code, creating the View and AppService layer, preliminary data transfer, page rendering. In these four steps, load the home page code, as described earlier; The creation of View and AppService layer is completed by wechat and is related to the user’s mobile phone, which is not under our control. What we can do is reduce initial data transfer time and page rendering time.

  1. We know that data objects in page.js are first rendered through a data pipeline to a view layer for page rendering. So we should control the size of this data object. For data that is not related to view rendering, do not put it in data, you can set a global variable to store it.
    Page({
        // Data related to page rendering is placed here
        data: {
            goods_list:[]
        },
        // Place data not related to page rendering here
        _data: {
            timer: null}})Copy the code
  1. Page rendering speed is also related to the DOM structure of HTML. There is very little room for optimization at this point, which is to write high-quality HTML code, reduce DOM nesting, and make the page render faster.

4.2 Make applets stronger


The next step is to add error information collection to small programs, including JS script error information collection and HTTP request error information collection. Some time ago, in the time work development, in order to better reuse and management, I made this error information collection function into a plug-in. However, making plug-ins is not as beautiful as imagined, and here’s more.

Script Error Collection

For script error collection, this is relatively simple because app.js provides an onError function that listens for errors

However, the error information is more detailed error information including stack and so on, and we don’t need such information when uploading, a waste of broadband, b look tired and useless. The information we need is: error type, error message description, error location.

thirdScriptError aa is not defined; at pages/index/index page test function ReferenceError: Aa is not defined at e. est (http://127.0.0.1:62641/appservice/pages/index/index.js:17:3) at e. < anonymous > (http://127.0.0.1:62641/appservice/__dev__/WAService.js:16:31500) at e.a (http://127.0.0.1:62641/appservice/__dev__/WAService.js:16:26386) at J (http://127.0.0.1:62641/appservice/__dev__/WAService.js:16:20800) at the Function. "anonymous > The at (http://127.0.0.1:62641/appservice/__dev__/WAService.js:16:22389) At http://127.0.0.1:62641/appservice/__dev__/WAService.js:16:27889 http://127.0.0.1:62641/appservice/__dev__/WAService.js:6:16777 at e. (anonymous function) (http://127.0.0.1:62641/appservice/__dev__/WAService.js:4:3403) at e (http://127.0.0.1:62641/appservice/appservice? T = 1543326089806, 1080:20291) at r.r egisterCallback. T (http://127.0.0.1:62641/appservice/appservice? t=1543326089806:1080:20476)Copy the code

This is the error message string, and we’re going to intercept it just by taking the information that we want. We find that this string is regular. The first line is the error type, the second line is the error details and location, and is “;”. Divide and separate. So it’s still easy for us to get the information we want.

    // Format error message
    function formateErroMsg(errorMsg){
        // do not let the collection of information affect the business
        try{
            var detailMsg = ' ';
            var detailPosition= ' ';
            var arr = errorMsg.split('\n')
            if (arr.length > 1) {
                Error details and error locations are separated in the second line
                var detailArr = arr[1].split('; ')
                detailMsg = detailArr.length > 0 ? detailArr[0] : ' ';
                if (detailArr.length > 1) {
                    detailArr.shift()
                    detailPosition = detailArr.join('; ')}}var obj = {
                // Error type is the first line
                error_type: arr.length > 0 ? arr[0] : ' '.error_msg: detailMsg,
                error_position: detailPosition
            };
            return obj
        }catch(e){}
    }
Copy the code

Once we get the information we want, we can send it to our service background for data collation and display. This requires the cooperation of the server, so we won’t go into details. We get the data, and the rest is nothing.

HTTP request error information Collection For HTTP request error information collection, we try not to use force burying point, each request before sending send after add our burying point. This is too much work and difficult to maintain. Therefore, we can intercept wx.request requests from the bottom up. Redefine request for WX objects using Object.definePropert. The concrete implementation is as follows

function rewriteRequest(){
	try {
      	const originRequest = wx.request;
		Object.defineProperty(wx, 'request', {
		  	configurable:true.enumerable: true.writable: true.value: function(){
				let options = arguments[0) | | {};// Do not collect error messages from the interface to prevent an endless loop
				var regexp = new RegExp("https://xxxx/error"."g");
				if (regexp.test(options.url)) {
				    // The original method is executed here
					return originRequest.call(this, options)
				}
				// Get the data after the request
				["success"."fail"].forEach((methodName) = > {
					let defineMethod = options[methodName];
					options[methodName] = function(){
						try{	      // Execute the original function in the redefinition function without affecting normal logic
						    defineMethod && defineMethod.apply(this.arguments);
						    // Start information collection
							let statusCode, result, msg;
							// The request failed
							if (methodName == 'fail') {
								statusCode = 0;
								result = 'fail';
								msg = ( arguments[0] && arguments[0].errMsg ) || ""
							}
							// Request successful,
							// The collection rule is:
							// statusCode is not 2xx,3xx
							// statusCode is 2xx,3xx, and result is not OK
							if (methodName == 'success') {
								let data = arguments[0) | | {}; statusCode = data.statusCode ||"";
								if (data.statusCode && Number(data.statusCode) >= 200 && Number(data.statusCode) < 400 ) {
									let resData = data.data ? (typeof data.data == 'object' ? data.data : JSON.parse(data.data)) : {};
									// Request successful, no collection
									if (resData.result == 'ok') {
										return;
									}
									result = resData.result || "";
									msg = resData.msg || "";
								}else{
									result = "";
									msg = data.data || ""; }}// Filter out sensitive information in the header
							if (options.header) {	
								options.header.userid && (delete options.header.userid)
							}
							// Filter out sensitive information in data
							if (options.data) {	
								options.data.userid && (delete options.data.userid)
							}
							
					        var collectInfo = {
								"url": options.url || ' '.// Request an address
								"method": options.method || "GET".// Request method
								"request_header": JSON.stringify(options.header || {}), // Request header information
								"request_data": JSON.stringify(options.data || {}), // Request parameters
								"resp_code": statusCode + ' '.// Request status code
								"resp_result": result, // Request a result
								"resp_msg": msg, // Request a description
					        }
					        // Submit parameters different from last time, or the same parameters, 1s later
					        if (JSON.stringify(collectInfo) ! = lastParams.paramStr || (new Date().getTime() - lastParams.timestamp > 1000)) {
					        	// Upload error information
					        	Post.post_error(_miniapp, 'http', collectInfo)
					        	lastParams.paramStr = JSON.stringify(collectInfo);
					        	lastParams.timestamp = new Date().getTime()
					        }

						}catch(e){
							//console.log(e);}}; })return originRequest.call(this, options)
			}
		})
	} catch (e) {
		// Do something when catch error}}Copy the code

In a plug-in free applet, we could execute the code above using the wx.request method, intercept the Wx.Request, and collect the HTTP request without adding any code. As mentioned above, this doesn’t work when we encapsulate it into a plug-in, because the applet doesn’t allow us to modify global variables when using plug-ins. So an error will be reported when the above code is executed. The next best thing to do is to encapsulate a wx.request method in the plugin. This method is actually wx.request sending, but in the plugin we can intercept wx.request. The concrete implementation is as follows:

    function my_request(){
        // Just execute the interceptor once! _isInit && rewriteRequest();return  wx.request(options)
    }
Copy the code

Now let’s look at the background data

Constant monitoring will help us find a lot of hidden bugs

4 summarizes


Yangyang sasa wrote so much, perhaps some places say not too clear, slowly exercise. Then the last few points just picked the important, I believe that there should be no problem with small program development experience of friends. Then there’s time to supplement and optimize. First here, predestined friends see, welcome message exchange.