尝试发送POST请求时,App脚本会发送405响应

Ach*_*ake 7 google-apps-script axios

我已经使用doPost方法公开发布了一个应用程序脚本(任何人,甚至是匿名的),如下所示,

 function doPost(e){
    var sheet = SpreadsheetApp.getActiveSheet();
    var length = e.contentLength;
    var body = e.postData.contents;
    var jsonString = e.postData.getDataAsString();
    var jsonData = JSON.parse(jsonString);
    sheet.appendRow([jsonData.title, length]);
    var MyResponse = "works";
    return ContentService.createTextOutput(MyResponse).setMimeType(ContentService.MimeType.JAVASCRIPT);
}
Run Code Online (Sandbox Code Playgroud)

当我使用带有Advanced Rest Client的JSON对象发送一个Post请求时,它全部工作并返回200 OK响应.但是当我尝试从本地托管的反应应用程序发送带有反应axios的发布请求时,它会发送405响应.

XMLHttpRequest cannot load https://script.google.com/macros/s/AKfycbzyc2CG9xLM-igL3zuslSmNY2GewL5seTWpMpDIQr_5eCod7_U/exec. Response for preflight has invalid HTTP status code 405
Run Code Online (Sandbox Code Playgroud)

我也在浏览器中启用了跨源资源共享.发送POST请求的功能如下,

axios({
          method:'post',
          url:'https://script.google.com/macros/s/AKfycbzyc2CG9xLM-igL3zuslSmNY2GewL5seTWpMpDIQr_5eCod7_U/exec',
          data: {
            "title": 'Fred',
            "lastName": 'Flintstone'
          }
        }).then(function (response) {
            console.log(response);
          })
          .catch(function (error) {
            console.log(error);
          });
Run Code Online (Sandbox Code Playgroud)

如果有人能指出我为什么收到405回复,那将是非常感激的.

Spo*_*oky 13

你错过了重要的部分:

预检的响应具有无效的HTTP状态代码405.

您的浏览器正在进行预检请求,该请求使用OPTIONSHTTP方法.这是为了检查服务器是否允许POST请求 - 405状态代码是在对OPTIONS请求的响应中发送的,而不是您的POST请求.

CORS预检请求是一个CORS请求,用于检查CORS协议是否被理解. 资源


此外,对于可能对服务器数据产生副作用的HTTP请求方法(特别是对于除某些MIME类型以外的HTTP方法GET或用于POST某些MIME类型),规范要求浏览器"预检"请求,从而请求支持的方法.服务器使用HTTP OPTIONS请求方法,然后,在服务器"批准"后,使用实际的HTTP请求方法发送实际请求. 资源
有些请求不会触发CORS预检.这些在本文中被称为"简单请求"[...]  来源
本文章节详细说明了请求必须满足的条件才被视为"简单请求".
[...]"预检"请求首先通过该OPTIONS方法向另一个域上的资源发送HTTP请求,以确定实际请求是否可以安全发送.跨站点请求是这样预检的,因为它们可能对用户数据有影响. 来源
本文章节详细介绍了导致请求被预检的条件.

在这种情况下,以下是导致请求被预检:

[...] 如果所述Content-Type报头具有比下面的其他值:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

Content-Type标头的值application/json;charset=utf-8由axios 设置.使用text/plain;charset=utf-8text/plain修复问题:

axios({
    method: 'post',
    url: 'https://script.google.com/macros/s/AKfycbzyc2CG9xLM-igL3zuslSmNY2GewL5seTWpMpDIQr_5eCod7_U/exec',
    data: {
        title: 'Fred',
        lastName: 'Flintstone',
    },
    headers: {
        'Content-Type': 'text/plain;charset=utf-8',
    },
}).then(function (response) {
    console.log(response);
}).catch(function (error) {
    console.log(error);
});
Run Code Online (Sandbox Code Playgroud)