通过 CURL 发送 ajax 请求

Posted

技术标签:

【中文标题】通过 CURL 发送 ajax 请求【英文标题】:Send ajax request through CURL 【发布时间】:2018-06-21 05:13:57 【问题描述】:

需要发送 API 请求。出于某种原因,服务器正在阻止 CURL 请求,但它批准了 XHR ajax 请求。我可以发送 ajax 请求,但出现了另一个问题 - 我的网站通过 HTTPS 提供混合内容,但需要发送的请求是通过 HTTP,因此我无法使用 ajax。

我正在寻找一种通过 CURL 模拟 ajax 请求的方法,以某种方式欺骗服务器相信 CURL 请求确实是一个 ajax 请求。

这是我尝试过的。

这是我的 CURL 请求。

    $ch = curl_init();
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64)');
        curl_setopt($ch, CURLOPT_REFERER, 'server's url');
        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Accept:application/json, text/javascript, */*; q=0.01',
        'Accept-Encoding:gzip, deflate',
        'Accept-Language:en-US,en;q=0.9',
        'Connection:keep-alive',
        'Content-Type: application/json; charset=utf-8',
        'X-Requested-With: XMLHttpRequest',
        '__RequestVerificationToken: $token'
        ));
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_COOKIEJAR, base_path().'/cookies.txt');
        curl_setopt($ch, CURLOPT_COOKIEFILE, base_path().'/cookies.txt');
        $buffer = curl_exec($ch);
        if(curl_error($ch))
        
        $buffer =   curl_error($ch);
        
        curl_close($ch);

return $buffer;

此 curl 请求被阻止

但是,这个 ajax 请求通过我的本地主机,但由于我的实时网站使用 HTTPS,我无法真正使用它。

     $.ajax(
          type: "get",
          xhrFields:  withCredentials:true ,
          url: http://apiendpoint.com,
          success: function(data)
          
           // console.log(data);
          
    )

【问题讨论】:

你怎么知道它被屏蔽了? (即,与根本不工作?)你得到什么 HTTP 状态? 通过ajax请求收到的响应是success,而curl请求响应是invalid 试试这个 -> curl_setopt($ch, CURLOPT_HTTPHEADER, array("X-Requested-With: XMLHttpRequest", "Content-Type: application/json; charset=utf-8")); 如果您在响应中看到文本“无效”,那么您并没有被阻止。请求已完成,您收到一条失败消息。尝试使用 -v(用于命令行)运行 curl 或运行 curl_getinfo()(用于 php curl)以转储额外信息。 @zuif xhr 来自浏览器,并具有发送到服务器的会话和 cookie。打开开发人员工具并查看 ajax 调用的请求标头 - 我怀疑您会在那里看到 cookie。作为测试,您应该能够(在 chrome 中我知道您可以)copy as curl 在命令行上运行该命令。它将添加来自浏览器的相关 cookie 和标头。如果您将这些添加到您的 php 代码中,它可能会起作用,但这不是长期的解决方案,因为它会因每个人而异。 【参考方案1】:

你可以使用两阶段请求

1 curl .... -c $cookie_file

2curl .... -b $cookie_file -c $cookie_file

这应该可行。 首先是获取带有会话 id 的 cookie 第二做真正的要求

【讨论】:

【参考方案2】:

我认为令牌的标头可能不是您认为的那样,因为给定 $a==1,'$a' 转换为 $a,但 "$a" 转换为 "1"(注意单引号与双引号)。

在您的示例中,尝试替换:

'__RequestVerificationToken: $token'

与:

"__RequestVerificationToken: $token"

如果这能解决问题,请告诉我们。

考虑使用 passthru("curl command here...");使用 lintabá 的建议

【讨论】:

谢谢。但是没有$token 变量,我看到一个例子提到了这个标头,并明确说明了$token,所以我也尝试了一个。 所以这不是导致问题的真正代码,而是某种形式的伪代码? @zuif 你应该发布不起作用的代码(隐藏任何有意义的数据),以便我们可以尝试调试它 @CliffBurton 我已经用有问题的 URL 更新了问题,请你检查一下,如果你能解决,请告诉我 为什么不在标题中的 : 后面加空格?【参考方案3】:

在 chrome 中,您可以从开发人员工具栏中复制有效的 curl 表达式。尝试使用 cli 中的那个。如果可行,您可以确定哪些部分是必需的,哪些部分不是。然后你可以把它转录成php。

如果您对 php 和 curl 是否发生同样的事情有疑问,请尝试使用 requestbin。

【讨论】:

我这样做了,我尝试使用完全相同的标题,但没有用。 没用过requestbin,怎么用?以及如何比较我的 curl 请求和浏览器请求? - 在 requestbin 上创建一个 bin。 (这将为您提供一个 url) - 用 curl 请求中的给定 URL 替换原始 url 并执行它 - 检查 requestbin 上的结果 - 使用 ajax 从您的站点向 requestbin url 发送请求 - 也检查新的 -比较两个结果 谢谢,好工具。我尝试发送与 requestbin 收到的完全相同的标头,但仍然无法正常工作:( 我已经用有问题的 URL 更新了问题,请你检查一下,如果你能解决,请告诉我

以上是关于通过 CURL 发送 ajax 请求的主要内容,如果未能解决你的问题,请参考以下文章

为每个 cURL 请求返​​回 AJAX 结果

如何通过php的curl模拟ajax请求,获取其返回值

如何通过 PHP 发送带有 pem 证书的 curl 请求?

如何在ajax中重现成功的curl调用

通过 Qt 发送 PUT 请求时错误的请求类型 PUT,适用于 curl

如何通过 Windows 批处理脚本中的 curl 发送带有 json 正文的 POST 请求