Our @nuxt/axios request gets a 401 error when we get some data on our home page that requires token authentication (for example, “/cates/oneCategory” request) and our user is not authenticated

  async asyncData({ $axios }) {
    // Get the first level of classification
    let { oneCategory } = await $axios.$get("/cates/oneCategory");
    
    // Process the classified data
    oneCategory = oneCategory.map((val) = > ({
        ...val,
        text: val.categoryName,
      }));
    
    return {
      // First level classification
      oneCategory,
    };
  },
Copy the code

$axios.onerror: $axios.onError: $axios.onError: $axios.onError: $axios.onError: $axios.onError: Nuxt’s default error page displays the 401 error page instead of the login page

import { Toast } from "vant";
import { httpcode } from "./httpcode";

export default function ({ $axios, store, redirect }) {
  // Request interceptor
  $axios.onRequest(() = > {
    const token = store.state.token;
    // If the token exists
    // Set the token using the setToken provided by @nuxt/axios
    token && $axios.setToken(token, "Bearer");
  });

  // Intercepts an error
  $axios.onError(err= > {
    // An error message is displayed according to the HTTP error code
    Toast.fail(httpcode[err.response.status])
    / / 404
    if (err.response.status === 404) return redirect("404");
    / / not authentication
    if (err.response.status === 401) {
      // Jump to the login page
      return redirect("/login")
      // Because onError is only asynchronous code for $axios, termination does not terminate the original page asyncData hook function}; })}Copy the code

Because onError is only asynchronous code for $axios, termination does not stop the original page’s asyncData hook function from continuingThis result is problematic and we need to display the login page properly. So, here are the key ideas to solve the problem:

Nuxt /axios source code: onError can get AxiosError error information, debugging can see that the error page is triggered after onError.

As we all know, $axios is wrapped by Promise. So we can infer that $axios should display the NUxt error page after promise.reject (401 error message) onError.

So if we return promise.resolve () before this, the 401 error will be avoided because of await $axios.$get(…) Resolve () before we get promise.reject ().

But return promise.resolve (), $axios.$get(….) Will be undefined,

So:

import { Toast } from "vant";
import { httpcode } from "./httpcode";

export default function ({ $axios, store, redirect }) {
  // Request interceptor
  $axios.onRequest(() = > {
    const token = store.state.token;
    // If the token exists
    // Set the token using the setToken provided by @nuxt/axios
    token && $axios.setToken(token, "Bearer");
  });

  // Intercepts an error
  $axios.onError(err= > {
    // An error message is displayed
    Toast.fail(httpcode[err.response.status])
    / / 404
    if (err.response.status === 404) return redirect("404");
    / / not authentication
    if (err.response.status === 401) {
      // Jump to the login page
      redirect("/login")
      // Because onError is only an asynchronous execution of $axios, termination does not terminate the execution of the original asyncData hook function

      // In order to solve the problem of the error page after the jump route,
      // Return prmoise.resolve () before returning promise.reject () to prevent jumping to the error page

      Reject ({data:{}});
      // At the very least, make sure that $get() gets the empty object {}, so that it does not jump to the error page again
      return Promise.resolve({ data: {}})}; })}Copy the code

Resolve ({data: {}}) return promise.resolve ({data: {}})

$axios.get() ¶ Resolve ($axios.get()) is the method before wrapping it.$get() takes the data object in get(). Resolve ({data:{}}); resolve({data:{}}); resolve({data:{}})

Otherwise, we may encounter the same errors when using data in hooks that are rendered in advance, such as asyncData

Finally, we need to determine whether the structured data is undefined every time we get data, and then use.

  async asyncData({ $axios }) {
    // Get the first level of classification
    let { oneCategory } = await $axios.$get("/cates/oneCategory");
    // Check whether the data is successfully obtained
    if (oneCategory)
      oneCategory = oneCategory.map((val) = > ({
        id: val.id,
        text: val.categoryName,
      }));
      
    // The oneCategory returned is undefined, but the page has been diverted. The original template will not be parsed, so the oneCategory will not be used
    return {
      // First level classification
      oneCategory,
    };
  },
  mounted() {
    console.log(Mounted will not execute);
  },
Copy the code

If you attempt to request the unauthenticated interface again, the login page is displayed