php 如何将 Curl 与 HEADERS 一起使用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9539466/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use Curl with HEADERS?
提问by Blank
I tried doing something like this but it doesn't work!
我试过做这样的事情,但它不起作用!
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://google.com/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('GET /search?q=kk HTTP/1.1
Host: www.google.de
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Proxy-Connection: Close
Cookie: PREF=ID=2bb051bfbf00e95b:U=c0bb6046a0ce0334:
Cache-Control: max-age=0
Connection: Close
'));
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Also, Is it possible to make the entire request with just headers without setting the URL? I mean without this?
另外,是否可以在不设置 URL 的情况下仅使用标头发出整个请求?我的意思是没有这个?
curl_setopt($ch, CURLOPT_URL, "http://google.com/");
Thanks!
谢谢!
回答by Mike Clark
I got it to work.
我让它工作。
1) Change header Host: www.google.de
to Host: www.google.com
1)将标题更改Host: www.google.de
为Host: www.google.com
Motivation: the host specified in the Host
header should match the URL's host exactly.
动机:Host
标头中指定的主机应与 URL 的主机完全匹配。
2) Use "www.google.com" instead of "google.com"
2) 使用“www.google.com”而不是“google.com”
Motivation: search requests made to google.com will not retrieve search results. You will be told to go to www.google.com.
动机:向 google.com 发出的搜索请求不会检索搜索结果。您将被告知去 www.google.com。
3) Set the full URL into CURLOPT_URL, not just the hostname. E.g. change the CURLOPT_URL to curl_setopt($ch, CURLOPT_URL, "http://www.google.com/search?q=kk");
3) 将完整的 URL 设置为 CURLOPT_URL,而不仅仅是主机名。例如将 CURLOPT_URL 更改为curl_setopt($ch, CURLOPT_URL, "http://www.google.com/search?q=kk");
Motivation: correct usage of cURL API.
动机:正确使用 cURL API。
4) Remove GET /search?q=kk HTTP/1.1
from CURLOPT_HTTPHEADER -- it's misplaced.
4)GET /search?q=kk HTTP/1.1
从 CURLOPT_HTTPHEADER 中删除——它放错了地方。
Motivation: correct usage of cURL API.
动机:正确使用 cURL API。
5) The response will be gzip or deflate compressed. To stop this, remove the Accept-Encoding: gzip, deflate
request header.
5) 响应将被 gzip 或 deflate 压缩。要阻止这种情况,请删除Accept-Encoding: gzip, deflate
请求标头。
Motivation: if you tell Google you're capable of receiving a compressed response, they will send you one. Decompressing an HTTP response is an extra step that you may not want to undertake. It may be easier to deal with the response if it is in an uncompressed text form.
动机:如果您告诉 Google 您能够接收压缩响应,他们会向您发送一个。解压缩 HTTP 响应是您可能不想进行的额外步骤。如果响应是未压缩的文本形式,则处理响应可能会更容易。
回答by fruchtose
To add onto what the other posters have said, you also cannot stick a GET
command in the CURLOPT_HTTPHEADER
array, because that's specified in the other cURL options. cURL is meant to be operated using the curl_setopt
function; you cannot bypass it by putting your HTTP message in the headers section. For instance, to ensure that your command is an HTTP GET
operation, you set CURLOPT_HTTPGET
to TRUE
(although by default cURL will send a GET
until you change it to something else).
要添加其他海报所说的内容,您也不能GET
在CURLOPT_HTTPHEADER
数组中粘贴命令,因为这是在其他 cURL 选项中指定的。cURL 旨在使用该curl_setopt
函数进行操作;您无法通过将 HTTP 消息放在 headers 部分来绕过它。例如,要确保您的命令是 HTTPGET
操作,您可以设置CURLOPT_HTTPGET
为TRUE
(尽管默认情况下,cURL 将发送 ,GET
直到您将其更改为其他内容)。
To address your question of why you can't get to the right URL, that's because you need to specify the entire pathname in CURLOPT_URL
, not just the host. So, you should really be writing curl_setopt($ch, CURLOPT_URL, "http://google.de/search?q=kk HTTP/1.1");
to set the URL.
要解决为什么无法访问正确 URL 的问题,那是因为您需要在 中指定整个路径名CURLOPT_URL
,而不仅仅是主机。所以,你真的应该写curl_setopt($ch, CURLOPT_URL, "http://google.de/search?q=kk HTTP/1.1");
来设置 URL。
Further, I have no idea why you put Connection: Close
in he HTTP headers for a GET
request. In that header, you're telling Google that you're closing the connection you have.; this is handled by curl_close($ch);
, so forget about that header. In fact, half the items in your HTTP headers have no place being there. For instance, why are you sending a cookie in a request to get search results? Make sure you know what each header does before you send it out. Otherwise, you have absolutely no way to tell if you are sending the correct headers or not.
此外,我不知道您为什么要Connection: Close
为GET
请求放入HTTP 标头。在该标题中,您告诉 Google 您正在关闭您拥有的连接。这是由 处理的curl_close($ch);
,所以忘记那个标题。事实上,您的 HTTP 标头中的一半项目都没有存在的地方。例如,为什么要在请求中发送 cookie 以获取搜索结果?在发送之前,请确保您知道每个标头的作用。否则,您绝对无法判断是否发送了正确的标头。
回答by David Souther
You've got a few problems, but they should be easy to sort out. First, you're setting the host in the header different than the host in the URL request, but since you're doing HTTP1.0, that isn't needed anyways.
您遇到了一些问题,但它们应该很容易解决。首先,您在标头中设置的主机与 URL 请求中的主机不同,但由于您使用的是 HTTP1.0,因此无论如何都不需要。
Second, you need each line in the HTTPHEADER as its own thing in the array, and you don't include the GET line.
其次,您需要 HTTPHEADER 中的每一行作为数组中自己的东西,并且不包括 GET 行。
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: en-gb,en;q=0.5',
'Accept-Encoding: gzip, deflate',
'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'Proxy-Connection: Close',
'Cookie: PREF=ID=2bb051bfbf00e95b:U=c0bb6046a0ce0334:',
'Cache-Control: max-age=0',
'Connection: Close'
));
(You clearly stole this from Firefox, and an old version at that, but we'll let it slide.) Finally, yes, you must specify CURLOPT_URL, that's just the way the cURL API is designed.
(您显然是从 Firefox 和旧版本那里偷来的,但我们会让它滑动。)最后,是的,您必须指定 CURLOPT_URL,这正是 cURL API 的设计方式。
回答by Another Code
If you need such a high level of control over the resulting HTTP request, I would recommend using raw socket functionsto manually send the request instead. The manual even has an example of doing a HTTP request with fsockets:
如果您需要对生成的 HTTP 请求进行如此高级别的控制,我建议使用原始套接字函数来手动发送请求。该手册甚至有一个使用 fsockets 执行 HTTP 请求的示例:
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
回答by Mārti?? Briedis
You should read the fine manual more carefully next time. There is an example how to add the fields: array('Content-type: text/plain', 'Content-length: 100')
, not everything in a one string, but fields are separate array elements.
下次您应该更仔细地阅读精美的手册。有一个如何添加字段的示例:array('Content-type: text/plain', 'Content-length: 100')
,不是一个字符串中的所有内容,但字段是单独的数组元素。