使用Curl和PHP:如何在POST请求中跟随重定向

6
我有一个脚本,可以向多个页面发送POST数据。但是,我在向某些服务器发送请求时遇到了一些困难。原因是重定向。下面是模型:
  1. 我向服务器发送POST请求
  2. 服务器响应:301 Moved Permanently
  3. 然后curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE)启动并跟随重定向(但通过GET请求)。
为了解决这个问题,我使用curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"),现在它会重定向,但不会包含我在第一个请求中发送的POST正文内容。如何强制curl在重定向时发送POST正文?谢谢!
以下是示例:
<?php 
function curlPost($url, $postData = "")
{
    $ch = curl_init () or exit ( "curl error: Can't init curl" );
    $url = trim ( $url );
    curl_setopt ( $ch, CURLOPT_URL, $url );
    //curl_setopt ( $ch, CURLOPT_POST, 1 );
    curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt ( $ch, CURLOPT_POSTFIELDS, $postData );
    curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, 30 );
    curl_setopt ( $ch, CURLOPT_TIMEOUT, 30 );
    curl_setopt ( $ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36");
    curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, TRUE);

    $response = curl_exec ( $ch );
    if (! $response) {
        echo "Curl errno: " . curl_errno ( $ch ) . " (" . $url . " postdata = $postData )\n";
        echo "Curl error: " . curl_error ( $ch ) . " (" . $url . " postdata = $postData )\n";
        $info = curl_getinfo($ch);
        echo "HTTP code: ".$info["http_code"]."\n";
        // exit();
    }
    curl_close ( $ch );
    // echo $response;
    return $response;
}
?>

将您的 PHP 代码与示例放在帖子中。 - Chetan Ameta
1个回答

12

curl正在遵循RFC 7231建议的做法,这也是浏览器通常对301响应所做的操作:

  Note: For historical reasons, a user agent MAY change the request
  method from POST to GET for the subsequent request.  If this
  behavior is undesired, the 307 (Temporary Redirect) status code
  can be used instead.

如果你认为那是不可取的,你可以使用CURLOPT_POSTREDIR选项进行更改,在PHP中似乎只有很少的文档记录,但libcurl文档对此进行了解释。通过设置正确的位掩码,你就可以让curl在跟随重定向时更改方法。

如果你控制这个服务器端,一个更简单的解决办法是确保返回307响应码而不是301。


1
哇,谢谢。在网上没有找到任何关于这个的信息。此外,php说:“注意:使用未定义的常量CURL_REDIR_POST_ALL”,因此没有定义这个常量,我只是使用了curl_setopt($ch,CURLOPT_POSTREDIR,3)。现在它运行得很好。再次感谢,你做得很好! - Александр Пушкин

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接