3

我有一段代码使用 curl 执行发布 http 请求并返回输出。我正在发出发布请求的网站具有从 http 到 https 的重定向。

当我向 https 端口发出 post 请求时,一切正常。当我对 http 端口执行相同的请求(并被重定向到 https 端口)时,我得到一个空字符串。拜托,谁能告诉我为什么它不起作用以及如何正确地做到这一点。

执行 post 请求的函数:

function curl_query($url, $username, $password, $payload) {
    $additionalHeaders = "";
    $process = curl_init($url);
    curl_setopt($process, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded',$additionalHeaders));
    curl_setopt($process, CURLOPT_HEADER, false);
    curl_setopt($process, CURLOPT_USERPWD, $username . ":" . $password);
    curl_setopt($process, CURLOPT_TIMEOUT, 30);
    curl_setopt($process, CURLOPT_POST, 1);
    curl_setopt($process, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($process, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($process, CURLOPT_MAXREDIRS, 4);
    curl_setopt($process, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);
    $return = curl_exec($process);
    return $return;
}

将查询从端口 80 重定向到端口 443 的 .htaccess 条目:

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

更新 经过一些调试后,我发现在初始 POST 并被重定向到新位置之后 curl 正在发送 GET 请求。是否可以将初始 POST 重新发送到新位置?

4

2 回答 2

2

今天遇到同样的问题,首先认为这是 curl 的错误。然而,在深入研究之后,我发现 RFC 2616 声明了以下关于重定向 POST 请求的内容:

301 - 永久移动:

如果收到 301 状态代码以响应 GET 或 HEAD 以外的请求,除非用户可以确认,否则用户代理不得自动重定向请求,因为这可能会改变发出请求的条件。

注意:当收到 301 状态码后自动重定向 POST 请求时,一些现有的 HTTP/1.0 用户代理会错误地将其更改为 GET 请求。


302 - Found: > 如果收到 302 状态码以响应 GET 或 HEAD 以外的请求,除非用户可以确认,否则用户代理不得自动重定向请求,因为这可能会改变发出了请求。> >> 注意:RFC 1945 和 RFC 2068 指定不允许客户端更改重定向请求的方法。然而,大多数现有的用户代理实现将 302 视为 303 响应,无论原始请求方法如何,都对 Location 字段值执行 GET。状态码 303 和 307 已被添加用于希望明确明确期望客户端做出何种反应的服务器。
303 - 请参阅其他:> 可以在不同的 URI 下找到对请求的响应,并且应该在该资源上使用 GET 方法检索。此方法的存在主要是为了允许 POST 激活脚本的输出将用户代理重定向到选定的资源。新的 URI 不是原始请求资源的替代引用。
307 - 临时重定向 > 如果收到 307 状态代码以响应 GET 或 HEAD 以外的请求,除非用户可以确认,否则用户代理不得自动重定向请求,因为这可能会改变发出了请求。
来源:https://www.rfc-editor.org/rfc/rfc2616#section-10.3.2(第62-65页)

因此,知道 curl 不能询问用户任何事情,对于 301 和 302 重定向,POST 转换为 GET 似乎是合理的(即使根据 RFC 这不是 100%)。

幸运的是,自 curl 7.19.1 (php 5.3.2) 以来,可以选择强制 curl 保留 POST 方法进行重定向:

CURLOPT_POSTREDIR

如果在设置 CURLOPT_FOLLOWLOCATION 并发生特定类型的重定向时应维护 HTTP POST 方法,则位掩码为 1(301 永久移动)、2(302 找到)和 4(303 请参阅其他)。

http://php.net/manual/en/function.curl-setopt.php

所以例子:

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_POSTREDIR, 7);
$response = curl_exec($ch);
curl_close($ch);
于 2015-07-02T23:05:47.220 回答
0

使用“CURLOPT_UNRESTRICTED_AUTH: true”继续向重定向请求发送身份验证参数。

使用“CURLOPT_POSTREDIR: true”继续向重定向请求发送带有 POST 参数的 POST 类型请求。

这些选项在@Arthur 链接中进行了描述:http: //php.net/manual/en/function.curl-setopt.php

于 2021-07-22T16:03:38.523 回答