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

Axios调用带HTTP触发器的Google Cloud Functions时出现超时问题

Google Cloud Functions HTTP触发器写入Google Sheets时,Axios请求超时问题排查与解决

问题场景

我正在用带HTTP触发器的Google Cloud Functions把数据写入Google Sheets,云函数代码如下:

exports.writeDataMaterialCollection = functions.https.onRequest( (req, res) => { 
  if (req.method === "POST") { 
    console.log(req.body); 
    res.set("Access-Control-Allow-Origin", "*"); 
    const sheets = google.sheets({ version: "v4" }); 
    var jwt = getJwt(); 
    var apiKey = getApiKey(); 
    var spreadsheetId = "sheetIDxxxxxxxxx"; 
    var range = "A:L"; 
    var row = ["data"]; 
    sheets.spreadsheets.values.append( { 
      spreadsheetId: spreadsheetId, 
      range: range, 
      auth: jwt, 
      key: apiKey, 
      valueInputOption: "RAW", 
      resource: { values: [row] } 
    }, (err, result) => { 
      if (err) { 
        throw err; 
      } else { 
        console.log(result.data.updates.updatedRange); 
        res.status(200).send(result.data.updates.updatedRange); 
      } 
    } ); 
  } 
} );

用curl发起POST请求时数据能正常写入:

curl -d '{"test": "wert"}' -X POST http://localhost:5001/XXXX/writeDataMaterialCollection

但在Vue.js里用Axios发起请求时,云函数返回throw new Error("Function timed out."),Axios代码:

axios( "http://localhost:5001/XXXXX/writeDataMaterialCollection", { 
  method: "POST", 
  headers: { 
    "content-type": "application/json", 
    "Access-Control-Allow-Origin": "*" 
  }, 
  data: { daten1: 23 } 
} ).then(response => (self.writeDataResult = response));

问题根源分析

  • 未处理OPTIONS预检请求:浏览器发起跨域POST请求时,会先发送OPTIONS预检请求,你的云函数只处理了POST方法,其他方法(比如OPTIONS)没有返回任何响应,导致函数一直挂起直到超时。
  • 客户端错误设置CORS头:Access-Control-Allow-Origin是服务器返回给客户端的响应头,不需要在Axios的请求头里设置,这属于多余操作,反而可能干扰请求处理。
  • 错误处理逻辑不当:当sheets.spreadsheets.values.append回调出现错误时,直接throw err在云函数HTTP触发器中不会正确返回错误响应,会导致函数进程异常,无法结束请求。

解决方案

1. 修正云函数的CORS与请求方法处理

确保处理所有HTTP方法,尤其是OPTIONS,并且在所有分支都返回响应:

exports.writeDataMaterialCollection = functions.https.onRequest(async (req, res) => {
  // 先设置CORS头,所有请求都需要
  res.set("Access-Control-Allow-Origin", "*");
  res.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
  res.set("Access-Control-Allow-Headers", "Content-Type");

  // 处理OPTIONS预检请求,直接返回204
  if (req.method === "OPTIONS") {
    res.status(204).send("");
    return;
  }

  if (req.method === "POST") {
    console.log(req.body);
    const sheets = google.sheets({ version: "v4" });
    const jwt = getJwt();
    const apiKey = getApiKey();
    const spreadsheetId = "sheetIDxxxxxxxxx";
    const range = "A:L";
    // 可以根据req.body来构造row,比如用传入的daten1
    const row = [req.body.daten1 || "default-data"];

    try {
      // 改用async/await方式,更易维护和错误处理
      const result = await sheets.spreadsheets.values.append({
        spreadsheetId: spreadsheetId,
        range: range,
        auth: jwt,
        key: apiKey,
        valueInputOption: "RAW",
        resource: { values: [row] }
      });
      console.log(result.data.updates.updatedRange);
      res.status(200).send(result.data.updates.updatedRange);
    } catch (err) {
      console.error("写入表格出错:", err);
      // 返回错误响应,而不是throw
      res.status(500).send(`写入失败: ${err.message}`);
    }
  } else {
    // 处理其他方法,比如GET,返回不允许的提示
    res.status(405).send("仅支持POST和OPTIONS请求");
  }
});

2. 修正Axios请求代码

移除不必要的Access-Control-Allow-Origin请求头,并加上错误捕获方便调试:

axios("http://localhost:5001/XXXXX/writeDataMaterialCollection", {
  method: "POST",
  headers: {
    "content-type": "application/json"
  },
  data: { daten1: 23 }
}).then(response => {
  self.writeDataResult = response;
}).catch(err => {
  console.error("请求出错:", err);
});

额外注意事项

  • 本地测试时,确保Google Cloud Functions emulator正常运行,端口和路径与请求一致。
  • 确认getJwt()和getApiKey()返回的凭据有效,具备操作目标Google Sheets的权限。
  • 部署到线上时,建议不要将Access-Control-Allow-Origin设为*,而是指定你的前端域名,提升安全性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:17:31