Nuxt.js中API调用顺序异常:二次请求先于用户信息请求
Got it, let's tackle this issue where your second API call runs before the user info (User ID/Client ID) is fetched. This is a classic async sequencing problem—since Axios requests are non-blocking, we need to make sure we wait for the user data to be ready before firing dependent API calls. Here are three practical solutions tailored for Nuxt.js:
1. Global Middleware (Recommended for All Pages)
If every page needs this user info, a global middleware is the cleanest approach. It runs before any page loads, ensuring user data is available everywhere.
Step 1: Create the Middleware
Make a new file middleware/auth.js:
export default async function ({ app, store, error }) { try { // Fetch user info first const userResponse = await app.$axios.get('/api/user-info') const userData = userResponse.data // Store the data in Vuex (so it's accessible across all pages) await store.dispatch('user/setUserInfo', userData) } catch (err) { // Handle errors (e.g., redirect to login if user is unauthorized) error({ statusCode: 401, message: 'Failed to load user info' }) } }
Step 2: Register as Global Middleware
Update nuxt.config.js to run this middleware on every page:
export default { router: { middleware: 'auth' // Runs before all page loads } }
Step 3: Use the Data in Your Pages
Now you can safely access the stored user info in any page's asyncData or methods:
// pages/your-page.vue export default { async asyncData({ app, store }) { // User info is already loaded from the middleware const { userid, clientid } = store.state.user.userInfo // Now fire your second API call with the required params const itemsResponse = await app.$axios.get(`/getItems?userid=${userid}&clientid=${clientid}`) return { items: itemsResponse.data } } }
2. Page-Level Sequential Async Calls
If you only need this logic on specific pages, you can chain the requests directly in the page's asyncData:
// pages/specific-page.vue export default { async asyncData({ app, error }) { try { // Step 1: Fetch user info first const userResponse = await app.$axios.get('/api/user-info') const { userid, clientid } = userResponse.data // Step 2: Wait for user data before calling the second API const itemsResponse = await app.$axios.get(`/getItems?userid=${userid}&clientid=${clientid}`) return { userInfo: userResponse.data, items: itemsResponse.data } } catch (err) { error({ statusCode: err.response.status, message: err.message }) } } }
3. Axios Interceptor (Auto-Add Params to All Requests)
For a hands-off approach, use an Axios interceptor to automatically inject the user ID/Client ID into every API call—no need to manually append params each time.
Step 1: Create the Axios Plugin
Make plugins/axios.js:
export default async function ({ $axios, store, error }) { // Add a request interceptor $axios.interceptors.request.use(async (config) => { // Check if user info is already in Vuex; if not, fetch it if (!store.state.user.userInfo) { try { const userResponse = await $axios.get('/api/user-info') await store.dispatch('user/setUserInfo', userResponse.data) } catch (err) { error({ statusCode: 401, message: 'User info unavailable' }) return Promise.reject(err) } } // Auto-inject userid and clientid into all request params const { userid, clientid } = store.state.user.userInfo config.params = { ...config.params, userid, clientid } return config }) }
Step 2: Register the Plugin
Update nuxt.config.js:
export default { plugins: ['~/plugins/axios.js'] }
How It Works
Now any Axios call you make (like $axios.get('/getItems')) will automatically have ?userid=X&clientid=Y appended to the URL—no manual string concatenation needed!
Key Notes
- Always add error handling (like the
try/catchblocks above) to handle cases where the user info request fails (e.g., expired auth tokens). - Using Vuex to store user info ensures you don't refetch the data on every page load (you can add a check to see if it's already present before making the request).
内容的提问来源于stack exchange,提问作者Ahmad Abed

