You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hoppscotch前置请求脚本fetch异步执行顺序异常求助

解决Fetch异步请求中Token获取与后续请求的顺序问题

问题描述

在JavaScript脚本中使用fetch获取认证Token时,出现异步执行顺序错误:本该先完成Token获取并存入环境变量,再发起后续业务请求,但实际后续请求在.then()链执行前就已触发,导致使用未初始化的Token。当前脚本能成功发起fetch请求,但后续目标URL请求先于Token设置完成,之后才执行.then()里的逻辑。

原代码

const authUrl = "https://auth0.com/oauth/token";
const authBody = JSON.stringify({
  grant_type: "password",
  client_id: "client_id",
  client_secret: "client_secret",
  scope: "openid profile email",
  audience: "https://audience/",
  username: "username",
  password: "password"
});
console.log("nach dem ziehen des token")
// Execute the fetch request to authenticate
fetch(authUrl, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: authBody
})
.then(response => response.json())
.then(data => {
  if (data.access_token) {
    // Set the access token in an environment variable
    pw.env.set("accessToken", data.access_token);
        pw.env.set("accessToken", data.access_token);
    console.log("accessToken set:", data.access_token); // to check the log
  } else {
    console.error('Error retrieving the token:', data);
  }
})
.catch(error => console.error('Error in fetching auth token:', error));

解决方案

核心思路是强制后续请求等待Token获取完成后再执行,以下提供两种实现方式:

方式一:使用async/await(代码更直观易读)

const authUrl = "https://auth0.com/oauth/token";
const authBody = JSON.stringify({
  grant_type: "password",
  client_id: "client_id",
  client_secret: "client_secret",
  scope: "openid profile email",
  audience: "https://audience/",
  username: "username",
  password: "password"
});

// 封装主逻辑为异步函数
async function handleAuthAndRequest() {
  try {
    // 第一步:获取并设置Token
    const authResponse = await fetch(authUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: authBody
    });
    const authData = await authResponse.json();

    if (authData.access_token) {
      pw.env.set("accessToken", authData.access_token);
      console.log("accessToken set:", authData.access_token);

      // 第二步:Token设置完成后发起后续请求
      await sendTargetRequest();
    } else {
      console.error('获取Token失败:', authData);
    }
  } catch (error) {
    console.error('认证请求出错:', error);
  }
}

// 封装后续业务请求
async function sendTargetRequest() {
  const token = pw.env.get("accessToken");
  const targetResponse = await fetch("你的目标URL", {
    headers: {
      'Authorization': `Bearer ${token}`,
      // 按需添加其他请求头
    }
    // 按需设置method、body等参数
  });
  
  const targetResult = await targetResponse.json();
  console.log("后续请求结果:", targetResult);
}

// 启动流程
handleAuthAndRequest();

方式二:优化Promise链式调用(保持原风格)

const authUrl = "https://auth0.com/oauth/token";
const authBody = JSON.stringify({
  grant_type: "password",
  client_id: "client_id",
  client_secret: "client_secret",
  scope: "openid profile email",
  audience: "https://audience/",
  username: "username",
  password: "password"
});

// 封装Token获取逻辑
function getAuthToken() {
  return fetch(authUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: authBody
  })
  .then(response => response.json())
  .then(data => {
    if (data.access_token) {
      pw.env.set("accessToken", data.access_token);
      console.log("accessToken set:", data.access_token);
      return data.access_token; // 将Token传递给下一个Promise链
    } else {
      throw new Error(`获取Token失败: ${JSON.stringify(data)}`);
    }
  })
  .catch(error => {
    console.error('认证请求出错:', error);
    throw error; // 抛出错误终止后续链
  });
}

// 封装后续业务请求
function sendTargetRequest(token) {
  return fetch("你的目标URL", {
    headers: {
      'Authorization': `Bearer ${token}`
      // 按需添加其他请求头
    }
  })
  .then(response => response.json())
  .then(result => {
    console.log("后续请求结果:", result);
    return result;
  })
  .catch(error => console.error('后续请求出错:', error));
}

// 按顺序执行:先拿Token,再发请求
getAuthToken().then(sendTargetRequest);

关键注意事项

  • 异步操作的本质:fetch是异步非阻塞函数,主线程会继续执行后续代码,.then()里的逻辑要等fetch请求完成后才会执行。所以必须把后续请求放在Token获取成功的回调/await之后。
  • 错误处理:无论用哪种方式,都要处理网络错误、Token获取失败的情况,避免后续请求因无有效Token而失败。
  • 避免冗余代码:原代码里重复调用了pw.env.set("accessToken", data.access_token);,建议去掉重复行。

内容的提问来源于stack exchange,提问作者LupefiascoMosdef

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:04:54