HTTP協議理解 + PHP使用curl函數發送Post請求的注意事項

HTTP協議理解

Content-Type:指定請求和響應的HTTP內容類型,默認爲text/html。
下面是幾個常見的Content-Type:
1. text/html
2. text/plain
3. text/css
4. text/javascript
5. application/x-www-form-urlencoded
6. multipart/form-data
7. application/json
8. application/xml
前面四個是html,css,javascript的文件類型,後面四個是POST的發包方式。

application/x-www-form-urlencoded是常用的表單發包方式,普通的表單提交,或者js發包,默認都是通過這種方式,

比如一個簡單地表單:

<form enctype="application/x-www-form-urlencoded" action="http://homeway.me/post.php" method="POST">
    <input type="text" name="name" value="homeway">
    <input type="text" name="key" value="nokey">
    <input type="submit" value="submit">
</form>

那麼服務器收到的raw header會類似:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4,gl;q=0.2,de;q=0.2
Cache-Control:no-cache
Connection:keep-alive
Content-Length:17
Content-Type:application/x-www-form-urlencoded

那麼服務器收到的raw body會是,name=homeway&key=nokey,在php中,通過$_POST就可以獲得數組形式的數據。

multipart/form-data用在發送文件的POST包。

這裏假設我用python的request發送一個文件給服務器:

data = {
“key1”: “123”,
“key2”: “456”,
}
files = {‘file’: open(‘index.py’, ‘rb’)}
res = requests.post(url=”http://localhost/upload”, method=”POST”, data=data, files=files)
print res
通過工具,可以看到我發送的數據內容如下:

POST http://www.homeway.me HTTP/1.1
Content-Type:multipart/form-data; boundary=——WebKitFormBoundaryOGkWPJsSaJCPWjZP

——WebKitFormBoundaryOGkWPJsSaJCPWjZP
Content-Disposition: form-data; name=”key2”
456
——WebKitFormBoundaryOGkWPJsSaJCPWjZP
Content-Disposition: form-data; name=”key1”
123
——WebKitFormBoundaryOGkWPJsSaJCPWjZP
Content-Disposition: form-data; name=”file”; filename=”index.py”
這裏Content-Type告訴我們,發包是以multipart/form-data格式來傳輸,另外,還有boundary用於分割數據。

當文件太長,HTTP無法在一個包之內發送完畢,就需要分割數據,分割成一個一個chunk發送給服務端,

那麼–用於區分數據快,而後面的數據633e61ebf351484f9124d63ce76d8469就是標示區分包作用。

參考鏈接:https://segmentfault.com/a/1190000003002851

php中的curl()函數進行post請求的時候,傳遞數據的格式可以有以下幾種方式:

1、由參數拼接而成的key=>value鍵值對字符串。形如以下: name=xxx&age=23$sex=1,這種請求參數默認是按照application/x-www-form-urlencoded進行編碼的。

2、由參數組成的key=>value鍵值對數組(只能是一維數組,更高維度的數組會報錯)。
形如以下格式,這種請求參數默認是按照multipart/form-data格式進行編碼的。

[ name="xxx" , age = 23 , sex = 男 ]

3、將多維數組進行http_build_query()進行處理,等到一個key=>value鍵值對格式的字符串。
如下,這種方式也是通過application/x-www-form-urlencoded進行編碼的,在接收方可以通過$_POST直接獲取。

$data = [
          "msg"=>"這是一條測試數據",
          "xxx" => "yyyy",
          "msg_data" => [
               "name"=>"sunms",
               "age"=>23,
               "sex"=>"男",
               "content"=>[
                      1,2,3
                     ]
            ],
       ];

將得到以下的字符串:

msg=這是一條測試數據&xxx=yyyy&msg_data[name]=sunms&msg_data[age]=23&msg_data[sex]=男&msg_data[content][0]=1&msg_data[content][1]=2&msg_data[content][2]=3

4、將多維數組轉換爲json格式的字符串,對字符串進行application/json格式編碼,在接收方通過file_get_contents(“php://input”)或者$GLOBALS[‘HTTP_RAW_POST_DATA’]的方式獲取傳遞過來的json格式的字符串,然後將json格式的字符串轉換爲數組進行處理。

$data = [];
$data_string = json_encode($data);
.....
//設置header信息
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
      'Content-Type: application/json',
      'Content-Length: ' . strlen($data_string))
);

注意:對於application/json格式編碼的數據,POSTfilegetcontents(php://input) GLOBALS[‘HTTP_RAW_POST_DATA’]的方式獲取。

參考文檔: http://www.jb51.net/article/98335.htm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章