草庐IT

php - Curl POST 作为 GET 执行

coder 2024-04-12 原文

我正在尝试用 PHP 开发一种浏览器。 到目前为止,我的 class 可以使用以下 Content Type 处理 GETPOST 请求:application/x-www-form-urlencoded.

现在我需要转到 JSON 格式。我已将 Content-Type header 设置为 application/json

事实是,对于这种类型,我遇到了以下问题:设置 POST 请求将导致 GET 请求。这真的很奇怪。

这是我的代码:

private function request($url, $reset_cookies, $post_data = null, $custom_headers = null)
{       
    // Create options
    $options = array(
        CURLOPT_URL               => $url,
        CURLOPT_RETURNTRANSFER    => 1,
        CURLOPT_HEADER            => 0,
        CURLINFO_HEADER_OUT       => 1,
        CURLOPT_FAILONERROR       => 1,
        CURLOPT_USERAGENT         => $this->user_agent,
        CURLOPT_CONNECTTIMEOUT    => 30,
        CURLOPT_TIMEOUT           => 30,
        CURLOPT_FOLLOWLOCATION    => 1,
        CURLOPT_MAXREDIRS         => 10,
        CURLOPT_AUTOREFERER       => 1,
        CURLOPT_COOKIESESSION     => $reset_cookies ? 1 : 0,
        CURLOPT_COOKIEJAR         => $this->cookies_file,
        CURLOPT_COOKIEFILE        => $this->cookies_file,
        CURLOPT_HTTPHEADER        => array('Accept-language: en'),

        // SSL
        /*
        CURLOPT_SSL_CIPHER_LIST   => 'TLSv1',
        CURLOPT_SSL_VERIFYPEER    => 1,
        CURLOPT_CAINFO            => dirname(__FILE__) . '/Entrust.netCertificationAuthority(2048).crt',
        */
    );

    // Add headers
    if (isset($custom_headers)) $options[CURLOPT_HTTPHEADER] = array_merge($options[CURLOPT_HTTPHEADER], $custom_headers);

    // Add POST data
    if (isset($post_data))
    {
        $options[CURLOPT_POST]          = 1;
        $options[CURLOPT_POSTFIELDS]    = is_string($post_data) ? $post_data : http_build_query($post_data);
    }

    // Attach options
    curl_setopt_array($this->curl, $options);

    // Execute the request and read the response
    $content = curl_exec($this->curl);

    print_r($options);
    print_r(curl_getinfo($this->curl, CURLINFO_HEADER_OUT));

    // Clean local variables
    unset($url);
    unset($reset_cookies);
    unset($post_data);
    unset($custom_headers);
    unset($options);

    // Handle any error
    if (curl_errno($this->curl))
    {
        unset($content);
        throw new Exception(curl_error($this->curl));
    }

    return $content;
}

为了说明我的问题,这里有一个例子:

CUrl 选项作为 Array:

Array
(
    [10002] => http://mywebsite.com/post/
    [19913] => 1
    [42] => 0
    [2] => 1
    [45] => 1
    [10018] => Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
    [78] => 30
    [13] => 30
    [52] => 1
    [68] => 10
    [58] => 1
    [96] => 0
    [10082] => C:\wamp\www\v2\_libs/../_cookies/14d0fd2b-9f15-4ac5-8fae-4246cc6cef49.cookie
    [10031] => C:\wamp\www\v2\_libs/../_cookies/14d0fd2b-9f15-4ac5-8fae-4246cc6cef49.cookie
    [10023] => Array
        (
            [0] => Accept-language: en
            [1] => RequestVerificationToken: 4PMxvJsQzFJ5oFt3JdUPe6Bp_geIj4obDJCYIRoU09PrrfcBSUgJT9iB3mXnGFc2KSlYrPcRHF7iHdQhGNu0GKLUzd5FywfaADbGS8wjhXraF36W0
            [2] => Content-Type: application/json
        )

    [47] => 1
    [10015] => {"usernameOrFeedId":"manitoba","feed_message_body":"Dummy message goes here"}
)

所以请求 header 对我来说似乎不错,但我可能错了。

这是 CUrl 发送的 真实 header :

GET /post/ HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Host: mywebsite.com
Accept: */*
Referer: http://mywebsite.com/post/
Cookie: ADRUM_BT=R%3a53%7cclientRequestGUID%3a9787a51b-b24d-4400-9d6a-efbd618c74c0%7cbtId%3a18790%7cbtERT%3a44; CSRFToken=o_eoIVji7pWclOsrLaJpZEbOFSBJBm851rHbH0Xqwdzw2tC5j07EAc23mlj-opWowgpj0RkHyiktl1cS6onBqI43afM1; WebSessionId=3aem0m2xpwmvesgphna5gaop; prod=rd101o00000000000000000000ffff0a5a2a74o80; AuthenticateCookie=AAAAAtsQgeb8+UXrJ+wa7CGVJKnqizEAo2bMuFvqvwYMAl1NRaa6z68LBRx9hiHzPBC8tYqiayHID6pHChGXB7VywemwTpGivcRQ3nRlUVuaYQKyxQt21p1mx7OMlLCsRA==; web_lang.prod=fr
Accept-language: en
RequestVerificationToken: 4PMxvJsQzFJ5oFt3JdUPe6Bp_geIj4obDJCYIRoU09PrrfcBSUgJT9iB3mXnGFc2KSlYrPcRHF7iHdQhGNu0GKLUzd5FywfaADbGS8wjhXraF34W0
Content-Type: application/json

如您所见,这是一个 GET 请求,发布数据看起来已经消失了。

我做错了吗?

最佳答案

您正在跟踪重定向,这意味着您获得 3xx 响应代码并且 curl 向新 URL 发出第二个请求。

curl 将根据特定的 3xx 代码执行操作,对于某些重定向,它会将请求方法从 POST 更改 为 GET - 启用 VERBOSE 将显示是否这样做。使 curl 更改方法的响应代码是 301、302 和 303。之所以这样做,是因为浏览器就是这样处理这些响应代码的。

libcurl 提供了一个名为 CURLOPT_POSTREDIR 的选项您可以使用它告诉 curl 更改特定 HTTP 响应的方法。使用它,即使在使用这些响应代码之一重定向后,您也可以让 curl 发送 POST。

关于php - Curl POST 作为 GET 执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30074918/

有关php - Curl POST 作为 GET 执行的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  3. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  4. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  5. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  6. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  7. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  8. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  9. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  10. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

随机推荐