天天看點

PHP 發送HTTP post請求發送和擷取

發送POST請求

和GET方法一樣,POST方法也是HTTP協定中的一個重要組成部分。POST方法一般用來向目的伺服器送出請求,并附有請求實體。

POST被設計成用統一的方法實作下列功能:

     o 對現有資源的注釋(Annotation of existing resources);

     o 向電子公告欄、新聞討論區,郵件清單或類似讨論組發送消息;

     o 送出資料塊,如将表格(form)的結果送出給資料處理過程;

     o 通過附加操作來擴充資料庫。

     o 也可用來上傳檔案。

在所有的HTTP的POST請求中,必須指定合法的内容長度(Content-Length)。

如果HTTP/1.0伺服器在接收到請求消息内容時無法确定其長度,就會傳回400(非法請求)代碼。

應用程式不能緩存對POST請求的回應,因為做為應用程式來說,它們沒有辦法知道伺服器在未來的請求中将如何回應。

POST方式和GET方法的最大差別就是把發送的資料和URI位址分離。請求參數是在http标題的一個不同部分(名為entity body)傳輸的,這一部分用來傳輸表單資訊,是以必須将Content-type設定為:application/x-www-form- urlencoded。

Post請求格式如下:

POST /login.asp HTTP/1.1

Accept: */*

Referer: http://www.wantsoft.com

Accept-Language: zh-cn,en-us;q=0.5

Content-Type: application/x-www-form-urlencoded

User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; .NET CLR 1.0.3705; .NET CLR 1.1.4322)

Host: www.wantsoft.com

Content-Length: 35

Pragma: no-cache

Cache-Control: no-cache

username=wantsoft&password=password   //post的資料

  php的post請求的sample如下:  

1: <;?php      
2:   $srv_ip = '127.0.0.1';//你的目标服務位址或頻道.      
3:   $srv_port = 80;      
4:   $url = '/helloworld/?r=helloworld'; //接收你post的URL具體位址       
5:   $fp = '';      
6:   $resp_str = '';      
7:   $errno = 0;      
8:   $errstr = '';      
9:   $timeout = 10;      
10:   $post_str = "username=demo&str=aaaa";//要送出的内容.      
11:         
12:   //echo $url_str;      
13:   if ($srv_ip == ''){      
14:    echo('ip or dest url empty<;br>');      
15:   }      
16:   //echo($srv_ip);      
17:   $fp = fsockopen($srv_ip,$srv_port,$errno,$errstr,$timeout);      
18:   if (!$fp){      
19:    echo('fp fail');      
20:   }      
21:   $content_length = strlen($post_str);      
22:   $post_header = "POST $url HTTP/1.1\r\n";      
23:   $post_header .= "Content-Type: application/x-www-form-urlencoded\r\n";      
24:   $post_header .= "User-Agent: MSIE\r\n";      
25:   $post_header .= "Host: ".$srv_ip."\r\n";      
26:   $post_header .= "Content-Length: ".$content_length."\r\n";      
27:   $post_header .= "Connection: close\r\n\r\n";      
28:   $post_header .= $post_str."\r\n\r\n";      
29:   fwrite($fp,$post_header);      
30:   while(!feof($fp)){      
31:    $resp_str .= fgets($fp,512);//傳回值放入$resp_str      
32:   }      
33:   fclose($fp);      
34:   echo($resp_str);//處理傳回值.      
35:   //unset ($resp_str);      
36: ?>      

擷取POST請求

一般我們都用$_POST或$_REQUEST兩個預定義變量來接收POST送出的資料。但如果送出的資料沒有變量名,而是直接的字元串,則需要使用其他的方式來接收。

方法一: 使用全局變量$GLOBALS['HTTP_RAW_POST_DATA']來擷取。

      在$GLOBALS['HTTP_RAW_POST_DATA']存放的是POST過來的原始資料。而$_POST或$_REQUEST存放的是PHP以key=>value的形式格式化以後的資料。 但$GLOBALS['HTTP_RAW_POST_DATA']中是否儲存POST過來的資料取決于centent-Type的設定,即POST資料時必須顯式示指明Content-Type: application/x-www-form-urlencoded,POST的資料才會存放到 $GLOBALS['HTTP_RAW_POST_DATA']中。(該部分需要php.ini中設定 always_populate_raw_post_data = On 才能行的通)

方法二: 使用file_get_contents("php://input")來擷取。

     對于未指定 Content-Type 的POST資料,則可以使用file_get_contents("php://input");來擷取原始資料。事實上,用PHP接收POST的任何資料都可以使用本方法。而不用考慮Content-Type,包括二進制檔案流也可以。 是以用方法二是最保險的方法。

1: echo "<br> Post Data is :<br>";      
2:   foreach($_POST as $key=>$val)      
3:   {      
4:       echo "key:$key,val:$val<br>";      
5:   }      
6:         
7:   $data = file_get_contents("php://input");      
8:   echo $data.'<br>';      
9:   echo $GLOBALS['HTTP_RAW_POST_DATA'];      

結果如下: