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

设置Content-Type为JSON的POST请求为何触发Google Apps Script的CORS拦截?

Google Apps Script Web App的CORS问题分析

这是一个由Google Apps Script部署的测试用Web App端点,作用是返回请求体内容:
https://script.google.com/macros/s/AKfycbxMPbzaWcCl1HqVMuiCmxUK-UtzXg4OdQEV3gON6rPszbkGrEzwNPJFN4qJxjT1b7KN-Q/exec

正常请求案例

使用fetch发送application/x-www-form-urlencoded类型的POST请求:

fetch(url2, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
     },
     body: 'name=John&time=2pm'
  })
  .then(response => response.text())
  .then(data => console.log(data))
  .catch(error => console.error(error));

请求正常返回结果:

{"name":["John"],"time":["2pm"]}

报错请求案例

将请求的Content-Type改为application/json后(当前body仍为表单格式):

fetch(url2, {
  method: 'POST',
  headers: {
      'Content-Type': 'application/json'
  },
  body: 'name=John&time=2pm'
})
.then(response => response.text())
.then(data => console.log(data))
.catch(error => console.error(error));

出现CORS报错:

Access to fetch at
'https://script.google.com/macros/s/AKfycbxMPbzaWcCl1HqVMuiCmxUK-UtzXg4OdQEV3gON6rPszbkGrEzwNPJFN4qJxjT1b7KN-Q/exec'
from origin 'https://example.org' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled. VM197:1

POST https

问题原因解析

这是Google Apps Script Web App的特定配置限制,并非通用CORS行为,核心原因在于预检请求的处理差异:

  1. 简单请求无需预检:当发送application/x-www-form-urlencoded类型的POST请求时,浏览器判定为「简单请求」,不会发送OPTIONS预检请求,直接发送POST。此时Google Apps Script的Web App会自动添加Access-Control-Allow-Origin等CORS响应头,请求正常完成。
  2. 非简单请求触发预检:设置Content-Type: application/json后,浏览器判定为「非简单请求」,会先发送OPTIONS预检请求,询问服务器是否允许跨域。但Google Apps Script Web App默认不处理OPTIONS请求,无法返回Access-Control-Allow-Origin等必要头,导致预检失败触发报错。

另外当前请求还存在格式不匹配的问题:设置了JSON类型的Content-Type,但body却是表单格式,正确的JSON body应为JSON.stringify({name: "John", time: "2pm"}),不过这不是CORS报错的直接原因,即使格式正确,预检请求的问题依然存在。

适配WordPress站点的解决思路

思路1:处理OPTIONS预检请求

在Google Apps Script中添加doOptions函数,手动返回CORS响应头,同时确保doPost也返回对应头:

// 处理OPTIONS预检请求
function doOptions(e) {
  return ContentService.createTextResponse('')
    .setMimeType(ContentService.MimeType.TEXT)
    .setHeaders({
      'Access-Control-Allow-Origin': '你的WordPress站点域名', // 或用*允许所有域名
      'Access-Control-Allow-Methods': 'POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type'
    });
}

// 处理POST请求
function doPost(e) {
  // 这里写你的请求处理逻辑,比如解析JSON请求体
  const requestBody = JSON.parse(e.postData.contents);
  // 返回处理结果并添加CORS头
  return ContentService.createTextResponse(JSON.stringify(requestBody))
    .setMimeType(ContentService.MimeType.JSON)
    .setHeaders({
      'Access-Control-Allow-Origin': '你的WordPress站点域名'
    });
}

思路2:改用简单请求格式

继续使用application/x-www-form-urlencoded类型的请求,避免触发预检,保持和第一次测试一致的请求方式即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:45:01