2014-04-29 25 views
2

我試過搜索,其他答案沒有幫助我。CURL不會正確發送POSTFIELDS到一些服務器

我試圖通過cURL發送POST數據,但它只能在的某些服務器上工作。是什麼賦予了?

我已經試過:

if (!empty($data) && $usePost) { 
    curl_setopt($ch, CURLOPT_POST, true); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 
} 

$data包含的products鍵和一個JSON字符串的值的數組。

我也試過明確使用查詢:

if (!empty($data) && $usePost) { 
    curl_setopt($ch, CURLOPT_POST, true); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); 
} 

但儘管如此,$_POST接收服務器上給我NULL

不知道該怎麼辦?

這裏是整個方法:

public static function execCommand($command, $ch,$data=array(),$cookie_file='genCookie.txt', $usePost = false) { 
    $url = $command; 
    if (!empty($data) && !$usePost) 
     $url .= '?' . http_build_query($data); 
    elseif (isset($data['sessionid'])) { 
     $url .= '?sessionid=' . $data['sessionid']; 
     unset($data['sessionid']); 
    } 

    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file); 
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file); 
    curl_setopt($ch, CURLOPT_HEADER, 0); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1); 
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:21.0) Gecko/20100101 Firefox/21.0'); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 

    if (!empty($data) && $usePost) { 
     curl_setopt($ch, CURLOPT_POST, true); 
     curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 
    } 

    return curl_exec($ch); 
} 

我試圖呼應$_REQUEST,所以錯誤不是在$_GET。我也試過file_get_contents('php://input'),但還是一無所獲。

發送和接收端都在Apache服務器上。

更大的問題是,它的工作對服務器,但只有一些忽略它。有沒有更安全,更跨平臺的方式來做到這一點?

+2

_What_服務器? IIS? Apache HTTPD? –

+1

你能粘貼你的完整捲曲設置塊嗎? –

+0

已更新。雙方都是Apache,當它發生時代碼在原始問題 – casraf

回答

0

原來的問題是接收服務器上的SSL。該請求正在作出HTTP而不是HTTPS,而不是給出錯誤或重定向,它只是在途中丟棄POST(可能重定向到HTTPS,但未能通過POST一起通過?)

4

我發現很難相信Curl沒有向某些服務器發送「後」字段(您共享的代碼看起來不錯)。我寧願假設你在這些服務器上如何處理POST有什麼問題,或者你在別處做錯了什麼。

如果你運行像一個示例代碼,您可以使用tcpdump

$ sudo tcpdump -nl -w - -s0 -A -c 500 tcp port 80 | strings 

現在解決:

<?php 

class Curl { 

    protected static function getCurlHandler($url, $data = false, $headers = false) { 
     $ch = curl_init(); 

     curl_setopt($ch, CURLOPT_URL, $url); 
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
     curl_setopt($ch, CURLOPT_HEADER, 0); 

     if($headers) { 
      curl_setopt($ch, CURLINFO_HEADER_OUT, true); 
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
     } 

     if($data) { 
      curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); 
     } 

     return $ch; 
    } 

    protected static function exec($ch) { 
     $output = curl_exec($ch); 

     // handle errors 

     curl_close($ch); 
     return $output; 
    } 

    public static function get($url, $headers = array()) { 
     $ch = self::getCurlHandler($url, false, $headers); 

     return self::exec($ch); 
    } 

    public static function post($url, $data = array(), $headers = array()) { 
     $ch = self::getCurlHandler($url, $data, $headers); 
     curl_setopt($ch, CURLOPT_POST, 1); 

     return self::exec($ch); 
    } 

    public static function put($url, $data = array(), $headers = array()) { 
     $ch = self::getCurlHandler($url, $data, $headers); 
     curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); 

     return self::exec($ch); 
    } 

    public static function delete($url, $data = array(), $headers = array()) { 
     $ch = self::getCurlHandler($url, $data, $headers); 
     curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE"); 

     return self::exec($ch); 
    } 

} 


Curl::post("http://www.google.com", array('q' => 'hello world')); 

你應該找到像這樣在tcpdump的輸出

POST/HTTP/1.1 
Host: www.google.com 
Accept: */* 
Content-Length: 13 
Content-Type: application/x-www-form-urlencoded 
q=hello+world 

的最後一行是最有意思的一點,它清楚地表明CURL向th發送了一個POST請求e所需數據。

1

你的選擇是使用wget基本上從下載位置的文件。這可能會慢一點,因爲您需要打開下載的文件並刪除該空間。我不確定它的規模很好,對於POST的請求並不會有好處。 cURL使用端口80,這是基本的瀏覽器端口。這意味着如果你可以通過瀏覽器訪問它,cURL將會起作用。

通過您提供的有限信息,我可以提供一些故障排除提示。

在這種情況下,我呼籲發起請求的客戶端服務器要發送信息到服務器 PHP服務器。

你應該做的第一件事就是確保它在你的服務器上正常工作。檢查你的源代碼。

第1步。嘗試提交表單並確保$_POST返回信息。如果是這樣,你可以繼續前進。如果它不是你有一個非常非常奇怪的錯誤。我很想知道你是否在這些不同的服務器上使用不同的操作系統。

第2步。檢查您的服務器sessionid。確保你的客戶期待他們通過GET來。我知道這看起來很明顯,但很多時候顯而易見的是失敗的根源。如果sessionid出現故障,您的服務器會做什麼?確保您處理腳本返回類似:

if(session_is_registered($_GET['sessionid']) { 
    echo "This is a registered session."; 
    $_POST['debugSessionExists'] = true; 
} else { 
    echo "This sesion does not exist."; 
    $_POST['debugSessionExists'] = false; 
} 

你應該能夠吐出返回數據的客戶端太感謝echo

第3步。對所有$_POST變量做同樣的事情並回應返回。

foreach($_POST as $key=>$value) { 
    echo "{$key} exists and has the value of $value.<BR />"; 
} 
echo "Done checking $_POSTs."; 

我建議這樣做的原因是因爲我不知道你怎麼一直在檢查你的$_POST值的日期和它不傷害,看看你的捲曲的響應讓你看不到的信息。這意味着您存儲$ _POST值的方式僅僅是不在某些服務器上傳輸,這就是您的失敗點。

我將有興趣瞭解通過這些結果返回的內容。

0

如前所述,您可能需要執行tcpdump以準確查看數據如何傳送到服務器。

你可能會運行與捲曲「期望」頭可禁用:

http://the-stickman.com/web-development/php-and-curl-disabling-100-continue-header/

通過禁用期待頭,還有一個PERF。避免客戶端和服務器之間的額外往返的好處,儘管繞過服務器端的額外檢查(例如,強制最大化POST主體大小等)。

希望它有幫助。

0

更重要的是,它在大多數服務器上都能正常工作,但只有一些服務器會忽略它。

POST發送正常,但服務器不同。對於初學者,比較PHP版本。

例如; since PHP 4.2.0 register_globals is off,如果接收端重用變量名稱,如$foo VS $_POST['foo'],可能會給出類似的NULL結果。

是否有更安全,更跨平臺的方式來做到這一點?

不,POST是發送數據的好方法。但請記住,除非使用加密或https,否則數據將通過網絡發送明文。