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