This is the second day of my participation in the August More text Challenge. For details, see:August is more challenging

Follow the article “build SSR mall with NuxtJS actual combat notes – initialization project” to continue our journey of moving bricks. There are deficiencies or any suggestions, welcome you to do not hesitate to make corrections. This article mainly introduces the configuration of AXIOS in vUE back-end rendering (SSR) project based on NuxtJS, the cancellation of the sending of repeated requests and the implementation of browser cross-domain requests in the development environment

Axios configuration

Install and use AxiOS

Install Axios was already selected when creating the project. If not, install it manually: NPM i@nuxtjs/AXIos. If you have installed axios as a module, you need to configure it in nuxt.config.js and add it to the modules array:

modules: ['@nuxtjs/axios']
Copy the code

You then get $AXIos (the imported module object starts with $) in the server context to request the data.

Configuration axios

In the plugins directory, create a new axios.js file and export a function by default. In the arguments of the function, you can get the context of nuxt. From this, we can decompose the parameters: $Axios for sending Ajax requests, redirect for forcing pages to redirect, route routing information and store vuex data.

Basic configuration

BaseURL (base path) and timeout (timeout) :

$axios.defaults.baseURL = process.env.BASE_URL
$axios.defaults.timeout = 100000
Copy the code

Projects are usually divided into four environments: dev, test, staging, and prod. BaseURL varies from environment to environment, so use process.env.base_URL instead. The specific configuration will be specifically written after the article.

Request to intercept

Unlike the native Axios, @nuxtjs/ Axios used in the Nuxt project provides methods officially called ‘helpers’. We can directly use onRequest(config) to configure request interception, such as request header with token:

$axios.onRequest(config= > {
  if (store.getters.token) {
    config.headers.authorization = 'Bearer ' + store.getters.token
  } 
  return config
})
Copy the code

The response to intercept

The response helpers are onResponse

$axios.onResponse(response= > {
  // Do some business needs
  const res = response.data
  return res
})
Copy the code

Error handling

Error handling helpers were onError(ERR), and the Message component of the Element-UI was introduced in advance for reporting errors to the user.

$axios.onError(error= > {
  console.log(error) // for debug
  const code = parseInt(error.response && error.response.status)
  if (code === 401) {
    // There are several specific common status codes for special treatment
  }

  let message = ' '
  if (error.response && error.response.data && error.response.data.error) {
    message = error.response.data.error.message
  } else if (error.request) {
    message = error.request
  } else {
    message = error.message
  }
  Message({
    message: message || 'Request error'.type: 'error'.duration: 5 * 1000
  })
  return Promise.reject(error)
})
Copy the code

It is important to note that errors may occur in three cases, and different error messages are returned in different cases:

  1. error.responseA value indicates that the request has been sent and received a response from the server, but the status code does not start with 2;
  2. error.requestA value indicates that the request was made but no response was received
  3. The rest is when the establishment request itself fails

I’ve written a post about more HTTP requests before, but if you’re interested in the HTTP Protocol in Detail

Add the configuration in nuxt.config.js

plugins: ['@/plugins/axios.js']
Copy the code

This way nuxt will find the files defined in the plugins to execute before initializing the main application, so the configuration we added to Axios will work.

Axios avoids double submissions

To prevent the same request from being submitted repeatedly in a very short period of time due to user shaking, in addition to throttling, you can also configure Axios to intercept requests from the cancellation perspective.

So what we’re going to do is for the same request, if it’s sent again before it’s finished, we’re going to cancel the last request. This works if we have a cancelToken configured in the config of an AXIos request.

let cancel // The function used to hold the cancellation request
axios({ 
    url: 'http://test.com'.cancelToken: new axios.CancelToken(c= > { // c is the function used to cancel the current request
        cancel = c 
    }) 
})
Copy the code

Axios passes us a parameter c, which is a function to cancel the current request, and we assign it to the variable cancel, so performing cancel() will cancel the current request.

We can set up an array requestList to hold all requests that have been sent. The requestList is an array that contains all requests that have been sent. If it does not exist, it is added to the array and waits for the request to return successfully before removing it from the array. If the request encounters an error, the request array is emptied. The specific code is as follows:

export default function ({ $axios, redirect, route, store }) {
  // Request list (anti-duplicate submission)
  const requestList = []
  / / get CancelToken
  const { CancelToken } = $axios
  
  // Request interception
  $axios.onRequest(config= > {
    // ...
    // Prevent duplicate submissions (cancel if this is a duplicate operation, otherwise mark the operation in the requestList)
    config.cancelToken = new CancelToken(cancel= > {
      const requestFlag =
        JSON.stringify(config.url) +
        JSON.stringify(config.data) +
        JSON.stringify(config.params) +
        '&' +
        config.method
      if (requestList.includes(requestFlag)) {
        // If the request tag already exists, cancel the request, otherwise add the request tag to the request list
        cancel() // Cancel the request
      } else {
        requestList.push(requestFlag)
      }
    })
  })

  // Response intercept
  $axios.onResponse(response= > {
    // ...
    // When the request returns, remove the request tag from the requestList
    const requestFlag =
      JSON.stringify(response.config.url) +
      JSON.stringify(response.config.data) +
      JSON.stringify(response.config.params) +
      '&' +
      response.config.method
    requestList.splice(
      requestList.findIndex(item= > item === requestFlag),
      1)})// Error handling
  $axios.onError(error= > {
    // ...
    requestList.length = 0 // Empty the list of requests
    const code = parseInt(error.response && error.response.status)

    // Error if not cancelled
    if(! $axios.isCancel(error)) { Message({message: message || 'Request error'.type: 'error'.duration: 5 * 1000})}})}Copy the code

Note:

  1. To determine whether it is the same request, the request URL + request parameter + request mode is combined into a string as the request marker. Note that the request parameters should includeconfig.dataconfig.paramsCorresponding to POST request and GET request respectively;
  2. Canceling the request will result in an error, which means it will go up$axios.onErrorBut the error is not an actual error and there is no need to notify the user through the Message component, so you can add a judgmentif (! axios.isCancel(error))Only unrequested cancellation errors are reported;
  3. Sometimes there are situations where requests need to be made in succession. This can be solved by adding a parameter to the request, such as:needRepeat: Math.round(Date.now() * Math.random()), so that the two requests will be due to the request parameterneedRepeatDifferent and are determined to be two different requests.

Cross domain

Install npmi@nuxtjs /proxy to solve the problem of cross-domain browser requests. Configure this in nuxt.config.js:

axios: { proxy: true // Open axios cross-domain},
proxy: { 
  '/api/': { 
    target: 'http://dev.frontend.api.xxx.com'.changeOrigin: true.pathRewrite: {}}}Copy the code

Note: ‘/ API /’ must be written, otherwise all requests will be broiled and the page will jump directly to the target address.

Reference: axios.nuxtjs.org/extend www.axios-js.com/