Web App 确实在 POST 请求上以 302 状态响应

Web App does respods with a 302 status on a POST request

我从 Chrome 扩展向部署为 Web 应用程序的 GAS 发出 POST 请求。 Chrome 扩展脚本是:

const fetchData = async (scriptURL, data) => {
        try {
            const response = await fetch(scriptURL, {
                mode: 'no-cors',
                method: 'POST',
                referrer: "",
                redirect: 'follow',
                body: JSON.stringify(data), 
                headers: {
                    'Content-Type': 'application/json',
                    'Access-Control-Allow-Origin':'*'
                }                        
            });                             
            if (response != "") var json = response.json();
            console.log('Success:', JSON.stringify(json));
        } 
        catch (e){console.log('Errors:', e.message)}       
            
        return json;
    }

Web 应用程序获取请求、处理它并 returns 一个 JSON 响应:

 function doPost(e){ 
          // processing
    return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);
}

尽管 Chrome 分机未恢复 body。 Chrome 在 DevTools->Network->Response 中给出错误“加载响应数据失败”。这是请求和响应 headers:

Request URL: https://script.google.com/macros/s/AKfycbzwUUktSYViIkE-kEc9-C73ztt6Mm14GTW9tEFezIdt/exec
Request Method: POST
Status Code: 302 
Remote Address: 173.194.220.100:443
Referrer Policy: no-referrer-when-downgrade
**Response headers**
access-control-allow-origin: *
alt-svc: h3-29=":443"; ma=2592000, h3-27=":443"; ma=2592000, h3-25=":443"; ma=2592000, h3-T050=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q043=":443"; ma=2592000
cache-control: no-cache, no-store, max-age=0, must-revalidate
content-encoding: gzip
content-length: 416
content-security-policy: script-src 'report-sample' 'nonce-DROk3lWJaG4CuCxaaXZ+iQ' 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http:;object-src 'none';base-uri 'self';report-uri /cspreport
content-type: text/html; charset=UTF-8
date: Mon, 06 Jul 2020 19:16:47 GMT
expires: Mon, 01 Jan 1990 00:00:00 GMT
location: https://script.googleusercontent.com/macros/echo?user_content_key=3VuZ5HCCoG5098DqNcdFBjLL5kKYEi5U0ifWB9YmhR6BwH8VqCvsX8_sSZeRVkJwP1fZuSegpbhbvW6kPGda1I-6C2vyPPLIm5_BxDlH2jW0nuo2oDemN9CCS2h10ox_1xSncGQajx_ryfhECjZEnOhtPz9z4I3dzdyyINU3UA0pwpiENh8R4k1UDc5fBUkkDEzr0xNxtlsP-6Y5oFxMMg&lib=MpU1M31wDqWrblgsshTKAbKcDiPyCPu1i
pragma: no-cache
server: GSE
set-cookie: SIDCC=AJi4QfGj_nmaK5xHhkEGWyyb7dSsxg04uiw5Jp1HBnHCqmfBXd2win3dnlpVNNPsFuGVbqfUZ71m; expires=Tue, 06-Jul-2021 19:16:47 GMT; path=/; domain=.google.com; priority=high
status: 302
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
**Request Headers**
:authority: script.google.com
:method: POST
:path: /macros/s/AKfycbzwUUktSYViIkE-kEc9-C73ztt6Mm14GTW9tEFezIdt/exec
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
content-length: 344
content-type: text/plain;charset=UTF-8
cookie: .........
origin: chrome-extension://gabejmdkdkojddbfifhcceicplhpdkmn
sec-fetch-dest: empty
sec-fetch-mode: no-cors
sec-fetch-site: none
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
x-client-data: CIe2yQEIorbJAQjBtskBCKmdygEI/rzKAQjAvcoBCOfIygEYm77KAQ==

看起来像是 CORS 问题(headers,或 google 服务器 returns 不透明响应等)。

既然如此,我建议修改如下。

修改点:

  • 根据我使用 doPost 使用 fetch 的 Web 应用程序的经验,我了解到可以使用以下简单脚本。 Ref

      fetch(url, { method: "POST", body: JSON.stringify(obj) })
        .then((res) => {
          console.log(res.status);
          return res.text();
        })
        .then((res) => console.log(res));
    
  • 在这种情况下,当使用headers时,我确认发生了CORS相关的错误。而且,在网络应用程序中,doPost(e)e.postData.contents 似乎与没有此 headers.

    相同

从上面的脚本,当你的脚本修改后,变成如下。

修改后的脚本:

const fetchData = async (scriptURL, data) => {
  var json;
  try {
    const response = await fetch(scriptURL, {
      method: 'POST',
      body: JSON.stringify(data),
    });
    if (response != "") json = await response.json();
    console.log('Success:', JSON.stringify(json));
  } catch (e) {
    console.log('Errors:', e.message)
  }
  return json;
}

async function main() {
  const res = await fetchData("https://script.google.com/macros/s/###/exec", {key1: "value1"});
  console.log(res);
}

main();
  • 我可以确认,当使用这个修改后的脚本时,请求 doPost.
  • 不会发生错误

注:

  • 在这个修改中,假设return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);response有值。当Google Apps 脚本出现错误时,上述修改后的脚本将不起作用。所以请注意这一点。

  • 我想一开始为了确认上面的脚本是否可以使用,比如我想推荐使用下面这个简单的示例脚本

      function doPost(e){ 
        return ContentService.createTextOutput(JSON.stringify(e)).setMimeType(ContentService.MimeType.JSON);
      }
    
  • 当您修改了 Web 应用程序的 Google Apps 脚本时,请将 Web 应用程序重新部署为新版本。由此,最新的脚本被反​​映到Web Apps。另外,请注意这一点。

参考文献: