Web App 在 POST 请求中执行 302 状态的 respods

Posted

技术标签:

【中文标题】Web App 在 POST 请求中执行 302 状态的 respods【英文标题】:Web App does respods with a 302 status on a POST request 【发布时间】:2020-10-27 00:06:27 【问题描述】:

我从 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 App 获取请求,对其进行处理并返回 JSON 响应:

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

虽然 Chrome 扩展没有返回 respose 正文。 Chrome 在 DevTools->Network->Response 中给出错误“无法加载响应数据”。以下是请求和响应标头:

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 的问题(标头或谷歌服务器返回不透明的响应等)。

【问题讨论】:

这能回答你的问题吗? XMLHttpRequest blocked by CORS policy when posting data to a Web App @OlegValter 我的理论是 OP 没有显示“跟随”网络请求,这发生在 OP 显示之后,然后 无法加载响应数据。如果只是 302,则没有任何错误原因。预检请求肯定会失败。而“no-cors”只会返回“不透明的过滤响应”(=== nothing)=> 这与 Chrome 扩展程序不会返回响应正文 一致。所以是的,这是一个猜测;) @TheMaster - 啊,我现在明白你的推理了,嗯。很高兴看到对此的一些澄清 - @Sturmer?当然,不透明的响应部分应该是你提到的。顺便说一句,可能相关(虽然不是欺骗目标):"Failed to load response data" 我为您的问题提出了修改后的脚本。你能确认一下吗?如果这不是您期望的结果,我深表歉意。 只需将 contentType 更改为“text/plain”。一切都会自行解决。 【参考方案1】:

在这种情况下,我建议修改如下。

修改点:

根据我使用fetch 使用doPost 的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相关的错误。而且,在 Web Apps 中,doPost(e) 中的 e.postData.contents 似乎在有和没有这个标头时是一样的。

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

修改脚本:

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 Apps 的 Google Apps 脚本时,请将 Web Apps 重新部署为新版本。这样,最新的脚本就会反映到 Web 应用程序中。另外,请注意这一点。

参考资料:

Web Apps Taking advantage of Web Apps with Google Apps Script

【讨论】:

@Sturmer - 请尝试在编辑之前先通知帖子的回复者(如果编辑不仅仅是修复错误)。仍然-感谢您找到错字-@Tanaike,response.json()中缺少承诺履行操作员@ @Oleg Valter 感谢您的评论。我可以理解它。 @Sturmer 感谢您的回复。很高兴您的问题得到解决。

以上是关于Web App 在 POST 请求中执行 302 状态的 respods的主要内容,如果未能解决你的问题,请参考以下文章

我的 POST ajax 请求在 Laravel 控制器上返回 302

JMeter POST 请求返回 200 OK 而不是 302(重定向)

为啥nodejs express服务器在我使用post时返回302?

AngularJS:POST请求返回302后发送的GET请求用于登录

301,302,303,307重定向区别

HTTP 状态消息 200 302 304 403 404 500 分别表示啥?