如何在API中等待Token获取完成后再发送后续请求?
问题分析与解决方法
你的问题出在两个核心点:
- 异步调用时机错误:
login().then(me())里的me()会直接立即执行,完全没等login的异步操作完成,应该把函数本身传给then,而不是执行后的结果。 - axios实例headers无法自动更新:创建
instance时,Authorization已经是Bearer undefined的静态字符串,后续给token变量赋值不会同步修改实例的headers配置。
下面是两种实用的解决方式:
方法一:登录后手动更新axios实例默认headers
修改后的代码如下:
const fastify = require('fastify')({ logger: true }); const axios = require('axios'); const fs = require('fs'); require('dotenv').config(); const username = process.env.USERNAME const password = process.env.PASSWORD let token const instance = axios.create({ baseURL: process.env.URL, headers : { 'Authorization': '' } }) async function login() { // 登录请求不需要token,直接用原生axios发送更稳妥 const response = await axios.post(`${process.env.URL}/login`, {username, password}) token = response.data['token']; // 登录成功后手动更新实例的默认headers instance.defaults.headers.common['Authorization'] = `Bearer ${token}`; console.log(token); } async function me() { const response = await instance.get('/me') console.log(response.data); } // 这里传me函数本身,不是执行me() login().then(me)
方法二:用axios请求拦截器自动注入token(更推荐)
这种方式适合后续多个接口都需要携带token的场景,无需每次手动更新配置:
const fastify = require('fastify')({ logger: true }); const axios = require('axios'); const fs = require('fs'); require('dotenv').config(); const username = process.env.USERNAME const password = process.env.PASSWORD let token const instance = axios.create({ baseURL: process.env.URL, }) // 添加请求拦截器,每次发请求前自动检查并注入token instance.interceptors.request.use(config => { if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, error => { return Promise.reject(error); }); async function login() { const response = await instance.post('/login', {username, password}) token = response.data['token']; console.log(token); } async function me() { const response = await instance.get('/me') console.log(response.data); } // 修正调用逻辑,等待login完成后再执行me login().then(me)
你也可以用async/await的写法替代then,代码逻辑更直观:
async function run() { await login(); await me(); } run();
内容的提问来源于stack exchange,提问作者Devin Bowen
相关产品推荐
相关产品推荐

