2016-02-07 235 views
0

也許我只是需要一雙清新的眼睛....cURL不發送POST數據

我需要POST後面的頁面.htaccess基本認證。我成功登錄並越過.htBA,然後POST到目標頁面。我知道腳本正在進入該頁面,因爲我正在記錄訪問。然而$ _POST是空的 - 從檢查var以及目標腳本不是按照它應該的方式工作都是明顯的。 (我控制所有頁面)。

我已經嘗試了很多下面的各種捲曲選擇組合無濟於事。我沒有從第二擊中得到任何錯誤。

謝謝。

$post_array = array(
    'username'=>$u, 
    'password'=>$p 
); 


// Login here 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, 'http://example.com/admin/login.php'); 
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0'); 
curl_setopt($ch, CURLOPT_COOKIEJAR, realpath('temp/cookies.txt')); 
curl_setopt($ch, CURLOPT_COOKIEFILE, realpath('temp/cookies.txt')); 
curl_setopt($ch, CURLOPT_COOKIESESSION, true); 
curl_setopt($ch, CURLOPT_HEADER, true); 
curl_setopt($ch, CURLOPT_MAXREDIRS, 10); 
curl_setopt($ch, CURLOPT_REFERER, 'http://example.com/index.php'); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_array)); 
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'method' => 'POST', 
    "Authorization: Basic ".base64_encode("$username:$password"), 
)); 
$logInFirst = curl_exec ($ch); 


/* Don't close handle as need the auth for next page 
* load up a new page */ 
$post_array_2 = array(
    'localfile'=>'my_data.csv', 
    'theater_mode'=>'normal' 
    ); 
//curl_setopt($ch, CURLOPT_POST, true); 
curl_setopt($ch, CURLOPT_COOKIEJAR, realpath('temp/cookies.txt')); 
curl_setopt($ch, CURLOPT_COOKIEFILE, realpath('temp/cookies.txt')); 
curl_setopt($ch, CURLOPT_COOKIESESSION, true); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
curl_setopt($ch, CURLOPT_REFERER, 'http://example.com/admin/post_here.php'); 
curl_setopt($ch, CURLOPT_URL, 'http://example.com/admin/post_here.php'); 
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_array_2)); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
//curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: multipart/form-data;', 
    "Authorization: Basic ".base64_encode("$username:$password"), 
)); 
$runAi = curl_exec($ch); 
$run_error = curl_error($ch); echo '<hr>'.$run_error.'<hr>'; 
curl_close($ch); 

下面是目標頁面(post_here.php)上的代碼,這會導致零計數。所以我知道目標腳本正在被擊中,並且基於輸出,沒有POST。

$pa = ' There are this many keys in POST: '.count($_POST); 
foreach ($_POST as $key => $value) { 
    $pa .= ' '.$key.':'.$value.' ---- '; 
} 
+0

您是否檢查發送到該頁面的檢查元素中的發佈數據或表單數據? # –

+0

'base64_encode(「$ username:$ password」)'''username'=> $ u,'password'=> $ p' - 這些應該是相同的嗎?即:使用'$ u'而不是'$ username'等 – RamRaider

+0

@RamRaider ...這個cURL是在一個函數和'$ username = $ u'中,其中$ u是函數params中聲明的,所以它們實際上是一個在同一個。 (這樣做是爲了一路調試)。謝謝。 – dmayo

回答

0

的錯誤是在所述第二請求:

curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_array_2)); 
// ... 
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: multipart/form-data;', 
    // ... 

您發送報頭Content-Type: multipart/form-data但數據被編碼爲application/x-www-form-urlencoded(由http_build_query())。

要在第二個請求上發佈的數據包含'localfile'=>'my_data.csv'。如果您想在第二個請求上傳文件,那麼內容類型是正確的(但不需要手動設置)。不要使用http_build_query(),而要將數組傳遞給CURLOPT_POSTFIELDS,因爲它是explained in the documentation

另外,對於文件上傳,您必須在文件名前加上@,並確保curl能夠找到該文件。要做到這一點,最好的方法是使用完整的文件路徑:

$post_array_2 = array(
    'localfile' => '@'.__DIR__'/my_data.csv', 
    'theater_mode' => 'normal' 
); 

上面的代碼假定my_data.csv位於同一目錄下的PHP腳本(不推薦)。您應該使用dirname()從腳本目錄導航到存儲CSV文件的目錄,以組成正確的路徑。

由於文檔還指出,由於PHP 5.5 @前綴已被廢棄,你應該使用文件上傳的CURLFile類:

$post_array_2 = array(
    'localfile' => new CURLFile(__DIR__'/my_data.csv'), 
    'theater_mode' => 'normal' 
); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_array_2); 

作爲一個方面說明,當你調用curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);這意味着允許curl與服務器協商身份驗證方法。但是你也發送標題"Authorization: Basic ".base64_encode("$username:$password"),這會消除任何協商,因爲它會強制Authorization: Basic。 (用戶,密碼)組合。您應始終使用curl_setopt(CURLOPT_USERPWD, "$username:$password")來告訴用戶和密碼。不建議手工製作Authorization標頭。

如果您確定Authorization: Basic是您需要的方法,那麼您可以使用 使用curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC)

+0

好的,這個答案是最接近的。我相信主要問題是在第二個請求中發送「POSTFIELDS」。 1)。我沒有拿出'http_build_query()',而是直接使用數組。 2)。在'HTTPHEADER' curl_setopt中,我保留「Content-Type:mulitpart/form-data」,並移除了數組的Authorization元素。 **結果**這保留了頁面的成功命中,就像在目標腳本中可以訪問正確的'$ _POST'一樣。謝謝 – dmayo

0

由於您使用的是'Content-Type: multipart/form-data;',,因此您不會在帖子內看到任何內容。只要刪除,你應該沒問題。

如果你想上傳一個文件(即my_data.csv),你需要遵循這樣的話:

## change your file name as following in your param 
'localfile'=> '@'.'./my_data.csv', 

## after that remove http_build_query() from post 
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_array_2); 

這會自動將您的文章添加頁眉multipart

您可以使用$_FILES變量來查看您上傳的文件。

最後,您可以觀察curl是否啓用詳細模式。

curl_setopt($ch, CURLOPT_VERBOSE, true); 

提示:在使用cookie時,始終貼近捲曲每curl_exec()你做了。否則,在每次發出請求後,它都不會寫入cookie文件!

+0

RE:我知道關於使用普通頁面寫入cookie的提示,他們需要將它們寫入瀏覽器的輸出中,以便設置它們。不知道cURL中的cookie。所以,我試了一下。我關閉了第一個cURL'curl_close($ ch)',然後我設置了'curl_init($ ch)'來引導第二個調用,並且我得到了401 Unauthorized。我甚至試圖設置HTTPAUTH和USERPWD無濟於事。隨着我如何寫它,我知道cURL成功擊中了這兩個頁面。不過謝謝。 – dmayo