You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

从JavaScript向Google Apps Script POST JSON时遇CORS跨域问题求助

解决Google Apps Script跨域请求(CORS)被拦截的问题

你遇到的核心问题是浏览器的预检OPTIONS请求没有被Google Apps Script正确处理,导致CORS策略拦截了你的POST请求。我来帮你拆解原因和解决方案:

为什么Postman能成功,浏览器却不行?

当浏览器发送带Content-Type: application/json的POST请求时,会先自动发送一个OPTIONS预检请求,用来确认目标服务器是否允许跨域操作。如果服务器没有处理这个OPTIONS请求,或者返回的响应头不符合要求,浏览器就会直接拦截后续的POST请求,抛出你看到的CORS错误。

而Postman这类工具不会触发预检请求,它会直接发送POST请求,所以能成功拿到响应——这也是为什么你在Postman里能看到Access-Control-Allow-Origin: *头,但浏览器根本没机会走到这一步。

你的GAS代码哪里出了问题?

你的doPost函数只处理了POST方法的请求,但完全没处理OPTIONS预检请求。另外,即使POST请求能走到返回步骤,你也没有明确设置CORS相关的响应头,这也会导致浏览器拒绝接收响应。

修改后的服务端代码

首先添加一个专门处理OPTIONS请求的函数,返回浏览器需要的CORS头:

function doOptions(e) {
  return ContentService.createTextOutput('')
    .setMimeType(ContentService.MimeType.TEXT)
    .setHeaders({
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type'
    });
}

然后修改你的doPost函数,确保返回的响应也带上CORS头,同时把MIME类型调整为更合适的JSON:

function doPost(e){
  var postData = JSON.parse(e.postData.contents);
  let responseContent = "It Works!";
  
  switch (postData.task) {
    case 'addRecord':
      const res = addRecord(postData.request);
      // 建议返回结构化的JSON响应,方便客户端处理
      responseContent = JSON.stringify({status: 'success', data: res});
      break;
    default:
      responseContent = JSON.stringify({status: 'error', message: 'Unknown task type'});
  }
  
  return ContentService.createTextOutput(responseContent)
    .setMimeType(ContentService.MimeType.JSON)
    .setHeaders({
      'Access-Control-Allow-Origin': '*'
    });
}

为什么这些修改能解决问题?

  1. doOptions函数会响应浏览器的预检请求,明确告诉浏览器:允许所有来源(*)访问,允许POST和OPTIONS方法,允许携带Content-Type头——这样预检就能顺利通过。
  2. 修改后的doPost返回了Access-Control-Allow-Origin头,确保浏览器接收POST响应时不会因为跨域被拦截;同时把MIME类型设为JSON,和返回的内容格式匹配,避免解析问题。

可选:客户端代码优化(用Fetch API更简洁)

你的原始XMLHttpRequest代码没问题,但用现代的Fetch API会更易读:

const data = JSON.stringify({"task": 'addRecord', "request": {"first_name": "Oliver"}});
fetch("https://script.google.com/macros/s/AKfycbwnOTv_-kFISLa-3S-vkEqZscgrmptlf9nAP6o7O8vQm6exnvg/exec", {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: data
})
.then(response => response.json())
.then(result => console.log('请求成功:', result))
.catch(error => console.error('请求失败:', error));

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

火山引擎 最新活动