Я пытаюсь опубликовать форму на удаленном веб-сайте через php cURL.
вот моя конфигурация cURL (я добавил несколько комментариев в комментариях):
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $action);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); //without this line the request is being sent with GET method (I can see that with curl_getinfo)
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); //$postData is an urlencoded string
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36');
curl_setopt($ch, CURLOPT_REFERER,$url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding: gzip, deflate',
'Accept-Language: en-US,en;q=0.8',
'Expect:',
'Content-Type: application/x-www-form-urlencoded',
'Connection: keep-alive',
'Cache-Control: max-age=0',
'Origin: http://XXX',
));
После выполнения такой конфигурации я получаю такой ответ:
string(610) "HTTP/1.1 302 Found
Location: http://XXX
Vary: Accept-Encoding
Content-type: text/html; charset=utf-8
Server: DWS
Content-Length: 15536
Accept-Ranges: bytes
Date: Wed, 17 Dec 2014 10:59:35 GMT
X-Varnish: 2567206754
Age: 0
Via: 1.1 varnish
Connection: keep-alive
HTTP/1.1 411 Length Required
Content-Type: text/html
Server: DWS
Content-Length: 357
Accept-Ranges: bytes
Date: Wed, 17 Dec 2014 10:59:35 GMT
X-Varnish: 2567207187
Age: 0
Via: 1.1 varnish
Connection: keep-alive
Я попытался добавить заголовок Content-Length в конфигурацию cURL:
'Content-Length: ' . strlen($postData)
Но тогда cURL дает сбой с ошибкой 52 (пустой ответ от сервера).
Чтобы убедиться, что длина содержимого, которую я указываю, на самом деле правильная, я попытался добавить пользовательскую строку в CURLOPT_POSTFIELDS (например, ‘foo = bar’) и установить Content-Length: 7, но в результате получилось так же.
Я также пытался скрыть весь код и использовать Zend 2 Http Client, но безуспешно.
Я думаю, что я прочитал все другие сообщения об ошибке cURL 52, но ни одна из них, похоже, не имела ничего общего с заголовком Content-Length, поэтому я надеюсь, что кто-то здесь может мне помочь.
Пожалуйста, дайте мне знать, если вам нужна дополнительная информация с моей стороны.
POST
запросить URL, указанный в $action
переменная возвращает перенаправление HTTP 302, в котором CURL отправит следующий запрос, используя GET
см. 2-й абзац здесь: http://curl.haxx.se/docs/manpage.html#-L.
Вы уже используете CURLOPT_CUSTOMREQUEST
чтобы обойти это, но это нужно CURLOPT_POSTREDIR
а также, как указано в Струны раздел здесь: http://evertpot.com/curl-redirect-requestbody/
Вы не должны явно устанавливать Content-Length
но пусть CURL справится с этим.
В качестве альтернативы вы можете вручную «следовать» Location
заголовок и использовать URL из этого заголовка в $action
переменная (может быть полезно попробовать это сначала для тестирования).
Других решений пока нет …