preface

Background to the case

  • Vue – 2.5.11
  • Vue-cli use templatewebpack-simple
  • HTTP request: Axios

Vue officially describes the compatibility of Internet Explorer versions as Internet Explorer 9+, that is, Internet Explorer 9 and later versions. After testing, Vuejs itself, the core framework of Vue, and the official core plug-ins of Ecology (VueRouter, Vuex, etc.) can be used normally in IE9.

Vue author Yu Xi’s study advice for Vue includes learning and using the new ECMAScript specification as much as possible in order to make the project more ecologically/engineered. At present, ES6/ES2015 is a standard with high usability and stability, and has complete documentation. Ruan Yifeng’s introduction to ECMAScript 6 has done a lot of document translation in China, and the development environment can be described as perfect. However, older browsers do not support the ES6 specification, especially Internet Explorer, and even the highest ie11 versions do not fully support the ES6 specification. This requires compatibility with all browsers that do not natively support ES6 features.

This paper will use Vue ecological development completed website, ie9 version as the basis of the compatible goal, to achieve full function of normal use of the comprehensive compatible solution.

ES6 compatible

On IE9, some of the new es6 objects and expressions are not supported. The solution is to use the Babel-Polyfill component, which translates ES6 code into ES5 code that can be recognized by lower-version browsers

npm i babel-polyfill --save-dev
Copy the code

Once installed, you can reference it directly in the first line of the project’s main entry file main.js

import 'babel-polyfill';
Copy the code

In the code generated by the project using vue-CLI, the root directory has a.babelrc file, which is the configuration file for the project using Babel. Add the “useBuiltIns”: “Entry” setting to the default generated template content. This is a setting that specifies what content needs to be polyfilled

UseBuiltIns has three Settings

  • false– Do nothing
  • entry– According to the browser version support, polyfill requirements are split and introduced, and only polyfills that are not supported by the browser are introduced
  • usage– Check the codeES6/7/8Load only the polyfill used in the code

The recommended setting is Entry, and the complete.babelrc content is as follows:

{
  "presets": [["env",
      {
        "modules": false."useBuiltIns": "entry"}]."stage-3"]}Copy the code

By adding this code, most of the project is compatible with ie9 versions

Number object

Even after using Babel-Polyfill for code translation, there were some new ES6 features that were left unaddressed, such as the parseInt and parseFloat methods for Number objects

Es6 migrates the global methods parseInt() and parseFloat() onto the Number object, leaving the behavior exactly the same. The goal is to gradually reduce the global approach and make the language more modular.

To solve this problem without importing a package, also add the following code to the project main entry file main.js (as early as possible, preferably after referencing babel-polyfill)

if (Number.parseInt === undefined) Number.parseInt = window.parseInt;
if (Number.parseFloat === undefined) Number.parseFloat = window.parseFloat;
Copy the code

RequestAnimationFrame method

Browser window. RequestAnimationFrame is used for timing cycle operation of an interface, similar to the setTimeout, main purpose is to press frame to redraw the web.

RequestAnimationFrame takes advantage of the refresh mechanism of the display and saves system resources. The basic idea of requestAnimationFrame is to synchronize the display with a fixed refresh rate (60Hz or 75Hz), which means it can only be redrawn 60 or 75 times per second at most. In addition, using this API, the page automatically stops refreshing once it is not in the browser’s current TAB. This saves CPU, GPU and power.

One thing to note, however, is that requestAnimationFrame is done on the main thread. This means that if the main thread is very busy, the animation of the requestAnimationFrame will be compromised.

Window. RequestAnimationFrame () method tells the browser you want to perform the animation and request the browser before the next redraw call the specified function to update the animation. This method takes as an argument a callback function that is called before the browser redraws.

Some third-party components use this method, such as some file upload, image processing components; When this type of component is used under IE9, it is reported

SCRIPT5007: Expected object.
Copy the code

Window. RequestAnimationFrame () the minimum compatible with ie version is 10, then compatible on ie 9 need to make requestAnimationFrame polyfill

(function() {
    var lastTime = 0;
    var vendors = ['ms'.'moz'.'webkit'.'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] | |window[vendors[x]+'CancelRequestAnimationFrame'];
    }
 
    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0.16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };
 
    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) { clearTimeout(id); }; } ());Copy the code

Gist: requestAnimationFrame polyfill

This part of the code is also executed as soon as possible at the site entrance

HTTP Network Request (cross-domain)

In most Web projects (JavaWeb as an example), Web pages and services (at least the Controller layer) are developed and deployed in the same project. Under the new model of big front end, we suggest that the front end and back end of the website be completely separated as far as possible. The benefits and significance of the front and back end separation are not described here.

Since the front and back ends are separated, the deployment must be independent of each other. Different access paths may cause cross-domain access problems (the same site, different port numbers are also cross-domain).

Set the context here:

  • CROS cross-domain support is fully enabled on the server
  • The HTTP component uses AXIOS
  • Axios setwithCredentialsTrue enables cross-domain access with cookie data

Older browsers (IE10 + or Chrome, FF) only need to complete the background to support cross-domain data requests

Axios uses the XMLHttpRequest object by default when making data requests. When it detects that the current request is cross-domain, Axios tests whether the browser supports the XDomainRequest object, and if it does, it uses it first.

The XMLHttpRequest object of Internet Explorer 8 / Internet Explorer 9 does not support cross-domain access. This object does not support cross-domain access until After Internet Explorer 10. Microsoft’s solution is to provide the XDomainRequest(XDR) object in IE8 / IE9 to solve the cross-domain problem. Although the object can be used to successfully access cross-domain and return data, it is still a semi-finished product with incomplete functions, and its use has many limitations:

  • XDR supports only GET and POST requests
  • XDR does not support custom headers if used by the serverheaderIs not available for authentication
  • The request headerContent-TypeThe value can only be set totext/plain
  • XDR does not allow cross-protocol requests. If a web page uses HTTP, it can only request the HTTP interface, but cannot access the HTTPS interface
  • XDR only accepts HTTP/HTTPS requests
  • When a request is made, it is not carriedauthenticationcookies

Microsoft provided a solution, but it was simply a weak point, unable to handle data requests in various scenarios, and axios was unable to handle cross-domain data requests in IE9.

Perfect solution: Proxy

While AXIos can no longer do anything about IE9 across domains, webPack, a solution packaged with front-end projects, offers an elegant and radical solution: proxies

devServer.proxy

Webpack’s devServer.proxy functionality is implemented by the HTTP-proxy-Middleware project

The idea is to broker the request at the target location as a front-end service for the local request, and since the proxy is local, there’s no cross-domain problem, axios will use the XMLHttpRequest object to do the data request, and everything’s back to normal, Headers, cookies, Content-Type, authentication and other content are passed to the server correctly.

Configuration of webpack.config.js in the project

devServer: {
    historyApiFallback: true.noInfo: true.overlay: true.proxy: {
        '/api': {
            target: 'http://localhost:8081/myserver'.pathRewrite: {
                '^/api': ' '}}}}Copy the code

The location of the specified in the configuration of the http://localhost:8081/myserver service agent for the local front-end service http://localhost:8080/api. Such as the need to read the user information of the original request is http://localhost:8081/myserver/user/zhangsan, agent, becomes http://localhost:8080/api/user/zhangsan.

The/API prefix represents the server, so when using AXIos, you need to prefix each server request with/API; Usually in project development, secondary encapsulation of data request component AXIOS is needed to achieve the purpose of unified setting of default parameters and unified data request entry, etc. At this time, unified adjustment of request prefix is only needed in the secondary encapsulation file.

However, WebPack’s DevServer.proxy is only available in development mode, not production mode. In the development mode, the debugging service can read the configuration content in Webpack.config. js for real-time proxy, while before deploying the project to the production environment, the project needs to be compiled and converted into static JS files. Without the support of the debugging service, it is naturally impossible to request proxy.

Nginx configuration

Although devServer.proxy only works in development mode, there are solutions for production mode as well; Usually Vue project in the final JS file, only need a static server, which takes NGINx as the optimal choice, lightweight, high performance, high concurrency, reverse proxy service are its advantages, here need to do the data request proxy function is used in nginx reverse proxy function

Add the following information to the conf/nginx.conf file

location /api/ {
    proxy_pass http://localhost:8081/myserver/;
}
Copy the code

The same configuration is the goal of the http://localhost:8081/myserver/ server location agent for the local service/API path, so that production environment of data requests and problem was solved

Personal original content, reproduced please explain the source

Full content: github.com/TerryZ