【问题标题】:PHP file_get_contents sends GET instead of POST sometimesPHP file_get_contents 有时发送 GET 而不是 POST
【发布时间】:2021-10-20 02:07:03
【问题描述】:

我有一个罕见的案例,我需要一些帮助。

我有两个域(AA 和 BB)使用完全相同的软件。在这个软件上,我做了一个 file_get_contents() 来检索一些数据。见下文调用:

        $data = ['1234'];
        $post = array( 'data' => $data );

        $jsonData = array(
            'origin' => $_SERVER['SERVER_NAME'],
            'lang' => $_SERVER["HTTP_ACCEPT_LANGUAGE"],
            'post' => $post,
        );
        $jsonDataEncoded = json_encode($jsonData);

        $response = file_get_contents( $url_to_call, null, stream_context_create(array(
            'http' => array(
                'protocol_version' => 1.1,
                'user_agent'       => 'My_Agent',
                'method'           => 'POST',
                'header'           => "Content-type: application/json\r\n".
                    "Connection: close\r\n" .
                    "Accept-language: en\r\n" .
                    "Accept: ".$_SERVER["HTTP_ACCEPT"]."\r\n" .
                    "Accept-encoding: ".$_SERVER["HTTP_ACCEPT_ENCODING"]."\r\n" .
                    "Content-length: " . strlen($jsonDataEncoded) . "\r\n",
                'content'          => $jsonDataEncoded,
            ),
            'ssl' => array(
                'verify_peer'      => false,
                'verify_peer_name' => false,
            ),
        )));

$url_to_call 是第三个域 (CC)。在 CC 上,我有一个路由系统,可以区分请求是 GET 还是 POST。在这种情况下,我只接受 POST 请求。

根据场景 file_get_contents() 发送一个 GET 而不是一个 POST。我画了一幅画来说明这些场景。在括号中,您有在每个场景中托管域的 IP 的一些数字,在 localhost 上是 127,在两个 VPS 上是 91 和 25:

花了几个小时研究这些案例并寻找信息后,我没有找到任何建议。我看到了这个问题:PHP sends GET instead of POST 但使用“Content-type: application/x-www-form-urlencoded”,这使得问题完全不同,因为没有预检这种 Content-type 和其他差异。

我应该看什么来发现我为什么会有这种行为?

谢谢。

【问题讨论】:

  • 我怀疑有一个 Location 标头是从触发 HTTP 重定向的服务器之一发送的。如果我没记错的话,PHP 流默认遵循重定向。
  • 感谢 Álvaro,我该如何搜索此 Location 标头。一切都在我的控制之下(没有共享主机),我没有设置任何 Location 标头。我唯一的重定向是在 cPanel 级别的所有托管服务器中从 http 到 https,但我确定 $url_to_call 调用 https。
  • 我想你可以从stream_get_meta_data()查看wrapper_data
  • 我对 stream_get_meta_data() 的用处研究得越多,我对这个答案的理解就越少。我正在使用file_get_contents,调用是正确完成的,但在某些情况下,在目标服务器(CC)上接收到的请求具有更改的标头,从POST到GET。我需要的是在哪里完成此更改,但我不知道如何跟踪此调用。使用 stream_get_meta_data() 我可以使用 fopen 检查打开的连接。有关如何将它与 file_get_contents() 一起使用或如何跟踪它的任何示例?
  • 您的标头所讲述的故事正是:您发出 POST 请求,然后服务器重定向到 https://xxxxxxxxxx.com/api/get_icons,您的客户端遵循重定向(作为 GET)。你需要弄清楚为什么CC 会这样做。

标签: php file-get-contents


【解决方案1】:

这是我请求后得到的:

Array
(
    [0] => HTTP/1.1 301 Moved Permanently
    [1] => Date: Wed, 18 Aug 2021 16:20:57 GMT
    [2] => Server: Apache
    [3] => Location: https://xxxxxxxxxx.com/api/get_icons
    [4] => Content-Length: 248
    [5] => Connection: close
    [6] => Content-Type: text/html; charset=iso-8859-1
    [7] => HTTP/1.1 200 OK
    [8] => Date: Wed, 18 Aug 2021 16:20:57 GMT
    [9] => Server: Apache
    [10] => Expires: Thu, 19 Nov 1981 08:52:00 GMT
    [11] => Cache-Control: no-store, no-cache, must-revalidate
    [12] => Pragma: no-cache
    [13] => Set-Cookie: PHPSESSID=866aabcab06944ab954ac5feb1d081ba; path=/;SameSite=Strict;Secure=true
    [14] => Access-Control-Allow-Origin: *
    [15] => Access-Control-Allow-Headers: content-type
    [16] => Access-Control-Max-Age: 600
    [17] => Access-Control-Allow-Credentials: true
    [18] => Upgrade: h2,h2c
    [19] => Connection: Upgrade, close
    [20] => Access-Control-Allow-Methods: GET, POST
    [21] => Cache-Control: max-age=0, no-cache, no-store, must-revalidate
    [22] => Pragma: no-cache
    [23] => Expires: Wed, 11 Jan 1984 05:00:00 GMT
    [24] => Content-Type: text/html; charset=UTF-8
) 

位置很好。

【讨论】:

  • 位置正是 file_get_contents 所指向的。
  • 但是这个 [0] => HTTP/1.1 301 Moved Permanently 是问题所在。如何搜索正在发生的事情?
  • 分类完毕,阿尔瓦罗,你搞定了。这是 cPanel 上的 https 重定向。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-20
相关资源
最近更新 更多