向 Web 应用程序发出 POST 请求会运行 doPost,但响应中出现 400 错误

问题描述 投票:0回答:2

场景:

我在 AWS 服务器上设置了一个 Wordpress 网站。我正在向 Google Apps 脚本 Web 应用程序发出 POST 请求并尝试记录响应。我的PHP代码如下:

$request_obj = array(
    'data' => array(
        'client_id' => $client_id,
        'email' => $email
    )
);

$request_data = json_encode($request_obj);

$url = WEB_APP_URL;

$webSafe = str_replace(['+', '/'], ['-', '_'], base64_encode($request_data));

$args = array(
    'method' => 'POST',
    'headers' => array(
        'Content-Type' => 'application/json'
    ),
    'body' => array(
        'data' => $webSafe
    )
);

$response = wp_remote_post($url, $args);    

在 GCP 中的云日志中,我可以看到正在接收请求并且正在运行 doPost 函数,根据函数的时间戳和日志

function doPost(e) {

  let request = JSON.parse(e.postData.contents)

  request = request.replace(/-/g, "+").replace(/_/g, "/").replace(/%3D/g, "=")
  request = forge.util.decode64(request) 

  console.log("request")
  console.log(request)

  const props = PropertiesService.getScriptProperties()
  props.setProperty(request.clientId, request.email)

  return ContentService.createTextOutput(`{
      "data": "success", 
      "code": 200
    }`).setMimeType(ContentService.MimeType.JSON)
  
}

但是我从 Apps 脚本得到的响应就好像我首先提出的请求无效:

{
   "headers":{
      
   },
   "body":"<!DOCTYPE html>\n<html lang=en>\n  <meta charset=utf-8>\n  <meta name=viewport content=\"initial-scale=1, minimum-scale=1, width=device-width\">\n  <title>Error 400 (Bad Request)!!1<\/title>\n  <style>\n    {margin:0;padding:0}html,code{font:15px\/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px} > body{background:url(\/\/www.google.com\/images\/errors\/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(\/\/www.google.com\/images\/branding\/googlelogo\/1x\/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(\/\/www.google.com\/images\/branding\/googlelogo\/2x\/googlelogo_color_150x54dp.png) no-repeat 0% 0%\/100% 100%;-moz-border-image:url(\/\/www.google.com\/images\/branding\/googlelogo\/2x\/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(\/\/www.google.com\/images\/branding\/googlelogo\/2x\/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}\n  <\/style>\n  <a href=\/\/www.google.com\/><span id=logo aria-label=Google><\/span><\/a>\n  <p><b>400.<\/b> <ins>That\u2019s an error.<\/ins>\n  <p>Your client has issued a malformed or illegal request.  <ins>That\u2019s all we know.<\/ins>\n",
   "response":{
      "code":400,
      "message":"Bad Request"
   },
   "cookies":[
      
   ],
   "filename":null,
   "http_response":{
      "data":null,
      "headers":null,
      "status":null
   }
}

即使我可以在 GCP 中看到 doPost 日志:

我有另一个从 Wordpress 站点发出的 POST 请求,除了请求对象之外,请求的详细信息是相同的。工作负载如下:

$request_obj = array(
  'data' => array(
    'nonce' => $nonce,
    'client_name' => $company_name,
    'product' => $payment_data->product_name,
    'license_information' => array(
      'subscription_id' => $license_data->id,
      'end_of_billing_cycle' => $payment_data->current_period_end,
      'last_payment' => $payment_data->current_period_start,
      'product' => $payment_data->product
    )
  )
);

问题:

什么情况下doPost还在运行时会抛出400错误?我有点不知所措,因为如果 HTTP 请求无效,Apps 脚本代码通常不会运行。

php wordpress google-apps-script google-cloud-platform post
2个回答
1
投票

这里是使用 wordpress api 的代码:

$args = array(
    'redirection' => 0,
    'body' => array(
        'data' => $webSafe
    )
);
$response = wp_remote_post($url, $args);    
$headers = wp_remote_retrieve_headers($response);
if (isset($headers['location'])) $response = wp_remote_get($headers['location']);

原因是 wp_remote_post 将 script.google.com 返回的 302 重定向处理为 307,但 script.google.com 希望它像 303 重定向一样处理(浏览器和curl都是这样做的)


0
投票

我通过切换到curl并添加接受标头来实现此工作:

$ch = curl_init();

curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: application/json", "accept: application/json"));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

if (curl_errno($ch)) {
  file_put_contents($log_file, 'Error occurred: ' . curl_error($ch), FILE_APPEND);
}

$response = curl_exec($ch);
© www.soinside.com 2019 - 2024. All rights reserved.