【问题标题】:Redirecting an HTTP POST重定向 HTTP POST
【发布时间】:2017-04-01 00:20:04
【问题描述】:

好的,所以在我的网络应用程序的 API 中,我有一个传入的 HTTP 发布请求。 我想将该 POST 请求传递到另一台服务器,而不会丢失 POST 标头中的数据。这可能吗?我会使用哪种类型的重定向? php示例?

编辑:HTTP 请求来自移动应用程序,而不是网络浏览器。

谢谢!

【问题讨论】:

标签: php http post redirect


【解决方案1】:

您可以使用 cURL 或套接字重新发布数据,但您不能真正重定向它。

使用 cURL 发布到 URL:

$ch = curl_init('http://www.somewhere.com/that/receives/postdata.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_POST));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);

【讨论】:

  • +1。不值得投反对票。很多人都推荐 CURL 作为这种约束的潜在解决方法。
【解决方案2】:
RewriteRule current-page.php http://www.newserver.com/newpage.php [NC,P]

那里的 P(代理)将保留 POST 数据。如果尚未打开 apache 代理模块,则需要打开它。

【讨论】:

  • 我对此持怀疑态度。在我能看到的地方有一个可行的例子吗? 编辑:我看到你提到代理... Apache 然后在该页面的结果中代理?
  • @brad 它会工作,但是是的,它是一个反向代理,因此它将通过 apache,所以它并不比 cUrl 解决方案好多少。
  • +1 这是正确的解决方案,PHP应该与它无关。 HTTP 服务器(如 Apache)和客户端(如 Firefox)旨在处理这些情况,这是它们遵守的 HTTP 规范的一部分。
  • 这根本不是一个很好的解决方案。您想通过您的服务器代理某人的网站吗?这不适用于 SSL,您将遇到 cookie、引用检查器等问题。
【解决方案3】:

我知道这是一个老问题,但这可能会对偶然发现这个问题的人有所帮助。您应该能够发送 HTTP 307 响应代码以使用户代理重定向到新 url 并继续使用相同的方法和数据。这个answer有更多细节

【讨论】:

    【解决方案4】:

    如果客户端(即移动应用程序)HTTP 库支持这一点,那么您可以从服务器返回 HTTP 307,其中指出“请求应使用另一个 URI 重复......使用相同的方法”。这本质上是一个临时重定向,但告诉客户端使用相同的方法,即 POST。

    发出请求的客户端必须能够相应地响应 HTTP 307 响应并使用相同的方法遵循重定向 - 对于许多库来说,这可能是一个额外的标志或设置。

    【讨论】:

      【解决方案5】:

      您不能告诉浏览器通过 HTTP 标头发出 post 请求。 location 标头将重定向,但仅适用于 GET 或 HEAD 请求。

      您可以通过显示带有隐藏表单的页面来解决此限制,方法属性设置为 POST,操作设置为您希望浏览器发布到的 URL,然后在页面加载时自动提交。示例:

      <body onload="document.getElementById('form').submit();">
        <form id="form" action="http://example.com/form_handler.php" method="POST">
          <input type="hidden" name="param_1" value="data">
        </form>
      </body>
      

      或者,您可以在服务器上发出 POST 请求,然后显示结果。

      【讨论】:

      • 这适用于非浏览器 Web 应用程序 api。没有javascript。
      • 如果被重定向的 POST 包含文件上传,也将不起作用。您必须往返文件的内容,并对其进行编码以免中断,并将其填充到隐藏的表单字段和/或文本区域中,从而迫使客户端再次上传。
      【解决方案6】:

      我使用以下代码重定向帖子。在我的情况下,我只使用 application/octet-stream 内容类型,因此请务必考虑到这一点。

      $request = file_get_contents ( "php://input" ); 
      
      $arrContextOptions=array(
              "http" => array(
                      "method" => "POST",
                      "header" =>
                      'Content-Type: application/octet-stream'. "\r\n".
                      'Content-Length: ' . strlen($request) . "\r\n",
                      "content" => $request,
              ),
              "ssl"=>array(
                      "allow_self_signed"=>true,
                      "verify_peer"=>false,
              ),
      );
      $arrContextOptions = stream_context_create($arrContextOptions);
      
      
      header ( "HTTP/1.1" );
      header ( "Content-Type: application/octet-stream" );
      
      $result =  file_get_contents('http://thenewaddress.yes.it.works', false, $arrContextOptions);
      
      file_put_contents("php://output", $result);
      

      【讨论】:

        【解决方案7】:

        我认为我将要采用的解决方案类似于:

        <?
        $url = 'http://myserver.com/file.php';
        
        foreach ($_POST as $key => $value) {
          $text .= (strlen($text) > 0 ? '&' : '');
          $text .= $key . '=' . $value;
        }
        
        header('Location: ' . $url . '?' . $text);
        exit;
        ?>
        

        谁能想到这是一个坏主意的原因?

        【讨论】:

          【解决方案8】:

          如果您想从 POST 请求中获取数据并将其简单地 POST 到另一台服务器,请使用 cURL

          --或--

          如果您想从 POST 请求中获取数据并在 POST 数据时将客户端重定向到其他服务器,请使用此方法...

          动态生成包含所有 POST 数据的表单。像这样的东西……

          echo "<form name=\"someform\" action=\"http://www.somewhereelse.com/someform.whatever\">";
          foreach ($_POST as $key=>$value) {
              echo "<input type=\"hidden=\" name=\"" . htmlspecialchars($key) . "\" value=\"" . htmlspecialchars($value) . "\" />";
          }
          echo "</form>";
          

          然后,在页面加载完成后使用一些 JavaScript 提交该表单...

          document.forms['someform'].submit();
          

          【讨论】:

          • 这是针对非浏览器 api... javascript 不是一个选项。
          • -1 如果我看到我的一位开发人员实现了这个 HTML/JS 解决方案,我们需要认真谈谈。
          • @Tyler,你有更好的解决方案吗?我在肯尼提到他没有使用浏览器之前发布了这个。由于我在上面指定的原因,代理方法是一个的想法。这整个问题一开始就代表了一个坏主意。我只是指出了唯一可行的方法,但同样,这对 Kenny 不起作用,因为他没有使用浏览器。因为这是一个常见问题,所以我留下了答案。
          猜你喜欢
          • 2016-06-13
          • 1970-01-01
          • 2016-01-19
          • 2014-07-29
          • 1970-01-01
          • 1970-01-01
          • 2018-03-18
          • 2016-07-30
          • 1970-01-01
          相关资源
          最近更新 更多