Плохой запрос. Подключение к сайтам через curl на хосте и системе
У меня есть это cURL
код в php.
curl_setopt($ch, CURLOPT_URL, trim("http://stackru.com/questions/tagged/java"));
curl_setopt($ch, CURLOPT_PORT, 80); //ignore explicit setting of port 80
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_HTTPHEADER, $v);
curl_setopt($ch, CURLOPT_VERBOSE, true);
Содержание HTTPHEADER
являются;
Proxy-Connection: Close
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1017.2 Safari/535.19
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=blabla
Connection: Close
Каждый из них отдельные элементы в массиве $v
,
Когда я загружаю файл на свой хост и запускаю код, я получаю:
ошибка 400, неверный запрос
Ваш браузер отправил неверный запрос.
Но когда я запускаю его в моей системе, используя командную строку PHP, я получаю
< HTTP/1.1 200 OK
< Vary: Accept-Encoding
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
< Content-Encoding: gzip
< Date: Sat, 03 Mar 2012 21:50:17 GMT
< Connection: close
< Set-Cookie: buncha cokkies; path=/; HttpOnly
< Content-Length: 22151
<
* Closing connection #0
,
Это происходит не только на stackru, это происходит, это происходит также на 4shared, но работает на Google и других.
Спасибо за любую помощь.
2 ответа
Это скорее комментарий, чем ответ: из вашего вопроса неясно, что конкретно вызывает ошибку 400, и что конкретно означает ее, или, более конкретно, ее источник.
Это вывод вашего сервера? Это какой-то отзыв (ответ на завиток), который вы выводите с помощью своего скрипта?
Чтобы лучше отлаживать вещи, я придумал немного другую форму конфигурации, которая может вас заинтересовать при использовании расширения curl. Есть хорошая функция под названием curl_setopt_array
который позволяет вам установить несколько параметров одновременно. Он вернет false, если один из параметров не удастся. Это позволяет вам полностью настроить ваш запрос. Таким образом, вы можете легче внедрить и заменить его со второй (отладочной) конфигурацией:
$curlDefault = array(
CURLOPT_PORT => 80, //ignore explicit setting of port 80
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_ENCODING => '',
CURLOPT_HTTPHEADER => array(
'Proxy-Connection: Close',
'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1017.2 Safari/535.19',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Encoding: gzip,deflate,sdch',
'Accept-Language: en-US,en;q=0.8',
'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3',
'Cookie: __qca=blabla',
'Connection: Close',
),
CURLOPT_VERBOSE => TRUE, // TRUE to output verbose information. Writes output to STDERR, or the file specified using CURLOPT_STDERR.
);
$url = "http://stackru.com/questions/tagged/java";
$handle = curl_init($url);
curl_setopt_array($handle, $curlDefault);
$html = curl_exec($handle);
curl_close($handle);
Это может помочь вам улучшить код и отладить вещи.
Кроме того, вы используете CURLOPT_VERBOSE
вариант. Это поместит подробную информацию в STDERR
- так что вы не можете отслеживать это больше. Вместо этого вы можете добавить его к выводу, чтобы лучше увидеть, что происходит:
...
CURLOPT_VERBOSE => TRUE, // TRUE to output verbose information. Writes output to STDERR, or the file specified using CURLOPT_STDERR.
CURLOPT_STDERR => $verbose = fopen('php://temp', 'rw+'),
);
$url = "http://stackru.com/questions/tagged/java";
$handle = curl_init($url);
curl_setopt_array($handle, $curlDefault);
$html = curl_exec($handle);
$urlEndpoint = curl_getinfo($handle, CURLINFO_EFFECTIVE_URL);
echo "Verbose information:\n<pre>", !rewind($verbose), htmlspecialchars(stream_get_contents($verbose)), "</pre>\n";
curl_close($handle);
Который дает вид следующего вывода:
Verbose information:
* About to connect() to stackru.com port 80 (#0)
* Trying 64.34.119.12...
* connected
* Connected to stackru.com (64.34.119.12) port 80 (#0)
> GET /questions/tagged/java HTTP/1.1
Host: stackru.com
Proxy-Connection: Close
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1017.2 Safari/535.19
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=blabla
Connection: Close
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
< Content-Encoding: gzip
< Vary: Accept-Encoding
< Date: Mon, 05 Mar 2012 17:33:11 GMT
< Connection: close
< Content-Length: 10537
<
* Closing connection #0
Который должен предоставить вам информацию, необходимую для отслеживания вещей, если они связаны с запросом / завитком. Затем вы можете легко изменить параметры и посмотреть, если это имеет значение. Также сравните версию curl, которую вы установили локально, с версией на сервере. Чтобы получить его, используйте curl_version
:
$curlVersion = curl_version();
echo $curlVersion['version']; // e.g. 7.24.0
Надеюсь, это поможет вам отследить ситуацию.
В соответствии с http://php.net/manual/en/function.curl-setopt.php попробуйте установить CURLOPT_ENCODING
в "gzip"
Кроме того, я бы старался избегать как можно большего количества строк заголовка, например, использовать CURLOPT_COOKIE
вместо Cookie: __qca__=blabla
или же CURLOPT_USERAGENT
РЕДАКТИРОВАТЬ: кажется, что вы не используете массив (ключ => значение) для CURLOPT_HTTPHEADER, не так ли? в этом случае используйте массив, а с другими вещами, как я написал, все будет в порядке. (как это сделать, прочитайте инструкцию:P)
надеюсь, это поможет.
Это сработало для меня
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('php://temp', 'w+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
$response = curl_exec($ch);
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";