Http 協議學習筆記 (燕十三老師)

Http 協議php

重要性:html

1. 不管之後用 WebService 仍是用 rest 做大型架構,都離不開。chrome

WebService = Http 協議 + XML編程

Rest = HTTP 協議 + Jsonjson

各類 API , 通常也是用 http + XML/json 來實現vim

2. 以及 Ajax 的學習數組

 

什麼是協議 ( 就是客戶端問服務器答)瀏覽器

計算機中的協議和現實中的協議是同樣的,一式雙份/多份. 雙方/多方都聽從共同的一個規範, 這個規範就能夠稱爲協議。計算機之因此能全世界互通,協議是功不可沒,若是沒有協議,計算機各說各話,誰都聽不懂.緩存

Ftp, http, smtp, pop, tcp/ip 協議的安全

 

Http 協議的工做流程

客戶端          服務器(Apache/Nginx/..../iis)

0: 原始狀態,客戶端和服務器之間沒有關係

鏈接: 就是網絡上的虛擬電路,像 QQ, 是和服務器一直鏈接

1: 創建鏈接,客戶端發送請求,服務器沿着鏈接返回響應信息

2: 客戶端收到響應(html 代碼)

3: 斷開鏈接

 

HTTP 請求信息和響應信息的格式

GET 請求

 

請求:

1. 請求行

請求方法: GET/POST/HEAD/PUT/DELETE/TRACE/OPTIONS

     HEAD 和 GET 基本一致,只是不返回內容,好比只是確認一個內容好比照片是否存在,不須要返回的時候,或只是檢測服務器的狀態

     WEB SERVER 未必容許或者支持這些方法,不支持的話會返回 405: Method is not allowed

     PUT 是用於往服務器上放資源
     TRACE: 是你用了代理上網,你想看看代理有沒有修改/篡改你的HTTP請求,能夠用TRACE測試
       OPTIONS: 用於查看服務器容許了那些方法

請求路徑: 也就是請求的資源,URL 的一部分

所用協議: 也就是請求全部的協議版本,基本都是 HTTP/1.1 

2. 請求頭信息: 如: Host: localhost。 頭信息和主體信息以前必須有一個空行,即便沒有主體信息。

  頭信息是很是豐富的,並且豐富的頭信息也是學習重點

3. 請求主體信息 (無關緊要)

 

響應

1. 響應行

協議版本

狀態碼: 用來反映服務器的響應結果,常見的

200 OK,服務器成功返回頁面

301/2, 永久/臨時重定向

304 Not Modified - 未修改,就是說取的是本地緩存。(原理是在服務器的響應頭信息中,有Last-Modified 和 E-Tag, 用來標誌服務端的文件是否修改,則再次請求的時候,客戶端的請求頭中會有 If-Modifed-since 和 If-None-Match 信息,來判斷是否須要從新請求

307 - 重定向中保護原有的請求數據,Get 沒有必要用, POST 會用到

404 NOT FOUND, 403 FORBIDDEN, 503 服務器內部錯誤

狀態文字:是用來描述狀態碼的,便於觀察

 

狀態碼

定義

1xx 報告

接收到請求,繼續進程,留做往後拓展

2xx 成功

操做成功接收,被理解,並被接受

3xx 重定向

爲了完成請求,必須採起進一步措施

4xx 客戶端出錯

請求的語法有錯誤或不能徹底被知足

5xx 服務器出錯

服務器沒法完成明顯有效的請求

 

 

2. 響應頭信息 (格式爲Key: value)

content-length: 接下來主體的長度

3. 響應主體 (可能有)

例:

HTTP/1.1 200 OK

content-type: text/html

content-length: 5

 

hello

 

Q:HTTP 協議必定要瀏覽器發送麼

A: 

 

POST 請求

1. 在使用 POST 發送請求是,頭信息中必需要加上 content-length 信息

2. 同時須要告訴服務器 content-type: application/x-www-form-urlencoded

常見的type 見附錄

text/xml

application/json

multipart/form-data

application/x-www-form-urlencoded

 


 

PHP + Socket 編程  發送 HTTP 請求

要求能模擬下載,註冊,登錄

 

 

 

 


 

 

 

 

 

附錄

HTTP 協議

1 HTTP協議的概念和歷史

1.1 什麼是HTTP協議

HTTP協議是超文本傳送協議(HyperText Transfer Protocol)的縮寫,它是萬維網(World Wide Web,www,也簡稱爲Web)的基礎。HTTP協議設計之初就是爲了實現Web的想法。HTTP協議位於TCP/IP協議棧的應用層。

咱們在瀏覽器的地址欄裏輸入的網站地址叫作URL(UniformResourceLocator,統一資源定位符)。就像每家每戶都有一個門牌地址同樣,每一個網頁也都有一個Internet地址。當你在瀏覽器的地址框中輸入一個URL或是單擊一個超級連接時,URL就肯定了要瀏覽的地址。瀏覽器經過超文本傳輸協議(HTTP),將Web服務器上站點的網頁代碼提取出來,並呈現出客戶端須要的網頁。

HTTP協議使用的默認端口是80,同時也支持自定義端口。

1.2 HTTP協議的歷史

HTTP協議到如今爲止總共經歷了3個版本的演化,第一個HTTP協議誕生於1989年3月。當時Berners-Lee向 CERN(Conseil Europeen pour la Recherche Nucleaire,歐洲核能研究所)提交了一篇名爲《信息管理的一個提議》的文章。文章中提出了www網絡的構想,不過僅僅在不少方面都只關注了概念,而沒涉及到細節。

第一個HTTP協議的版本是HTTP 0.9,它的組成極其簡單,由於它只容許客戶端發送GET這一種請求,它不包含協議頭,每一個請求只有一句話,例如:

GET /index.html

因爲沒有協議頭,形成了HTTP 0.9協議只支持一種內容,即純文本。不過網頁仍然支持用HTML語言格式化,同時沒法插入圖片。因此HTTP 0.9可以支持的應用實在太有限了。一次HTTP 0.9的傳輸首先要創建一個由客戶端到Web服務器的TCP鏈接,由客戶端發起一個請求,而後由Web服務器返回頁面內容,而後鏈接會關閉。若是請求的頁面不存在,也不會返回任何錯誤碼。

HTTP 0.9的缺點是顯著的,但至少實現了第一代的Web。

HTTP協議的第二個版本是HTTP 1.0,直到HTTP 1.0成爲最重要的面向事務的應用層協議。該協議對每一次請求/響應,一樣是創建並關閉一次鏈接。其特色是簡單、易於管理,因此它符合了你們的須要,獲得了普遍的應用。

而且HTTP 1.0最顯著的變化之一是開始支持客戶端經過POST方法向Web服務器提交數據。今後客戶端與Web服務器之間再也不只能單向地獲取數據,而能夠實現交互,所以CGI(Common Gate Interface,通用網關接口)開始流行起來,Web上開始出現留言板、論壇等豐富的應用。

HTTP 1.0還有個顯著的變化是經過HTTP協議頭能夠支持各類媒體類型。今後Web上再也不僅僅是純文本的頁面,好比圖像經過<img>的HTML標記開始出現。

除了以上幾個新特性,HTTP 1.0支持長鏈接(但默認仍是使用短鏈接),緩存機制,以及身份認證。

雖然說HTTP協議的設計是向前兼容的,但目前不少瀏覽器和Web服務器都強制要求HTTP協議版本至少是1.0。

HTTP協議的第三個版本是HTTP 1.1,它就是目前使用最普遍的協議版本。這個版本的HTTP協議已經穩定了,跟HTTP 1.0相比,它新增了不少引人注目的新特性,好比Host協議頭,一個HTTP請求的頭中能夠包含一句例如:

Host: vimer.cn

今後一個Web服務器能夠支持掛載多個域名了,無需每一個域名都使用獨立IP,每一個網站可使用虛擬主機。

另外一個HTTP 1.1的新特性是支持部份內容請求/響應,這意味着當客戶端請求的數據量很大時,能夠分屢次發起請求,每次請求只要求獲取整塊數據的一部分。Web服務器也能夠分屢次響應,每次只返回整塊數據的一部分。這使得流媒體得以實現。

從HTTP 1.1開始,客戶端默認與Web 服務器創建長鏈接,這種鏈接適合Web上數據量較大的豐富應用,使得資源消耗更少。

QzHTTP就是一個支持HTTP 1.1協議的Web Server。

2.HTTP協議內容介紹

2.1 URI

HTTP協議經過URI(Uniform Resource Identifiers,統一資源定位符)來訪問資源。根據RFC 1808的官方定義,一個完整URI的組成以下:

http://myname:mypass@www.vimer.cn:80/mydir/myfile.html?myvar=myvalue#myfrag

 

URI字段

表 2.1

URI部分

意義

http

協議名稱

myname

用戶名(可選)

mypass

密碼(可選)

www.vimer.cn

主機網絡地址

80

端口號(可選)

/mydir/myfile.html

資源路徑

myvar=myvalue

查詢字符串(可選)

myfrag

錨點(可選)

可見協議名稱用「://」結束,用戶名和密碼以「:」分隔,以「@」結束,端口號與主機網絡地址以「:」分隔,資源路徑與查詢字符串以「?」分隔,錨點以#開頭。

而且,只有協議名稱、主機網絡地址和資源路徑是必須包含在URI裏的。

一個更常見的例子以下:

http://www.vimer.cn/

在這裏面,http是協議,www.vimer.cn是主機網絡地址,注意末尾的/就是資源路徑,這是必須的。當咱們平時使用Web瀏覽器訪問時,只須要輸入www.vimer.cn就能夠訪問,這是因爲Web瀏覽器替咱們自動補齊了前面的http://和最後的/,Web瀏覽器發起請求時使用的URI仍是完整的,Web瀏覽器並不強制用戶輸入格式規範的URI。

 

2.2 HTTP請求與響應

HTTP協議的交互主要由請求和響應組成,請求是指客戶端發起向Web服務器請求資源的消息,而響應是Web服務器根據客戶端的請求回送給客戶端的資源消息。

發出的請求信息(Request Message)包括如下幾部分:

l  請求行,例如GET /images/logo.gif HTTP/1.1,表示從/images 目錄下請求logo.gif 這個文件。

l  (請求)頭,例如Accept-Language: en

l  空行

l  可選的消息體

請求行和標題必須以<CR><LF> 做爲結尾(也就是,回車而後換行)。空行內必須只有<CR><LF>而無其餘空格。在HTTP/1.1 協議中,全部的請求頭,除Host外,都是可選的。

請求方法(Request Method)

HTTP/1.1協議中共定義了八種方法(有時也叫「動做」)來代表Request-URI指定的資源的不一樣操做方式:

l  OPTIONS

返回服務器針對特定資源所支持的HTTP請求方法。也能夠利用向Web服務器發送’*’的請求來測試服務器的功能性。

l  HEAD

向服務器索要與GET請求相一致的響應,只不過響應體將不會被返回。這一方法能夠在沒必要傳輸整個響應內容的狀況下,就能夠獲取包含在響應消息頭中的元信息。

l  GET

向特定的資源發出請求。注意:GET方法不該當被用於產生「反作用」的操做中,例如在Web 應用程序中。其中一個緣由是GET可能會被網絡蜘蛛等隨意訪問。

l  POST

向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會致使新的資源的創建和/或已有資源的修改。

l  PUT

向指定資源位置上傳其最新內容。

l  DELETE

刪除指定資源。

l  TRACE

回顯服務器收到的請求。

l  CONNECT

HTTP/1.1協議中預留給可以將鏈接改成管道方式的代理服務器。

方法名稱是區分大小寫的。當某個請求所針對的資源不支持對應的請求方法的時候,服務器應當返回狀態碼405(Method Not Allowed);當服務器不認識或者不支持對應的請求方法的時候,應當返回狀態碼501(Not Implemented)。

HTTP服務器至少應該實現GET和HEAD方法,其餘方法都是可選的,可選方法中還有一個重要的方法是POST。固然,全部的方法支持的實現都應當符合下述的方法各自的語義定義。此外,除了上述方法,特定的HTTP服務器還可以擴展自定義的方法。

一個GET請求的示例如圖2.3所示:

untitled 

圖2.3 HTTP請求

 

GET 表明方法名,後面的/表明資源路徑,HTTP/1.1表示協議版本。下面都是協議頭部分,常見的頭字段如表2.2所示。

 

HTTP協議頭字段

表2.2

頭字段

定義

Accept

客戶端能夠處理的媒體類型(MIME-Type),按優先級排序;在一個以逗號爲分隔的列表中,能夠定義多種類型和使用通配符

Accept-Language

客戶端支持的天然語言列表

Accept-Encoding

客戶端支持的編碼列表

User-Agent

客戶端環境類型

Host

服務器端的主機地址

Connection

鏈接類型,默認爲Keep-Alive

HTTP協議是Web內容的容器。一個示例HTTP響應如圖2.4所示:

 

untitled2 

圖2.4 HTTP響應

 

每一個響應由HTTP協議頭和Web內容構成。Web服務器收到一個請求,就會馬上解釋請求中所用到的方法,並開始處理應答。服務器的響應消息也包含頭字段形式的協議頭。響應的格式在RFC2616中定義以下:

Status-Line*

(( general-header)| response-header | entity-header)CRLF)

CRLF

[ message-body ]

響應消息的第一行是狀態行(Stauts-Line),由協議版本以及數字狀態碼和相關的文本短語組成,各部分間用空格符隔開,除了最後的回車或換行外,中間不容許有回車換行。

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

狀態碼是試圖理解和知足請求的三位數字的整數碼, 緣由短語(Reason-Phrase)是爲了給出的關於狀態碼的文本描述。狀態碼用於控制條件,而緣由短語(Reason-Phrase)是讓用戶便於閱讀。客戶端不須要檢查和顯示緣由短語。

狀態碼的第一位數字定義響應類型。後兩位數字沒有任何分類角色。第一位數字有五種值,如表2.3所示。

 

HTTP響應狀態碼

表 2.3

狀態碼

定義

1xx 報告

接收到請求,繼續進程

2xx 成功

步驟成功接收,被理解,並被接受

3xx 重定向

爲了完成請求,必須採起進一步措施

4xx 客戶端出錯

請求包括錯的順序或不能完成

5xx 服務器出錯

服務器沒法完成顯然有效的請求

下面列舉了爲HTTP/1.1定義的狀態碼值,和對應的緣由短語(Reason-Phrase)的例子。

l  客戶端錯誤

「100″ : Continue  繼續

「101″ : witching Protocols  交換協議

l  成功

「200″ : OK

「201″ : Created 已建立

「202″ : Accepted 接收

「203″ : Non-Authoritative Information 非認證信息

「204″ : No Content 無內容

「205″ : Reset Content 重置內容

「206″ : Partial Content 部份內容

l  重定向

「300″ : Multiple Choices 多路選擇

「301″ : Moved Permanently  永久轉移

「302″ : Found 暫時轉移

「303″ : See Other 參見其它

「304″ : Not Modified 未修改

「305″ : Use Proxy 使用代理

「307″ : Temporary Redirect

l  客戶方錯誤

「400″ : Bad Request 錯誤請求

「401″ : Unauthorized 未認證

「402″ : Payment Required 須要付費

「403″ : Forbidden 禁止

「404″ : Not Found 未找到

「405″ : Method Not Allowed 方法不容許

「406″ : Not Acceptable 不接受

「407″ : Proxy Authentication Required 須要代理認證

「408″ : Request Time-out 請求超時

「409″ : Conflict 衝突

「410″ : Gone 失敗

「411″ : Length Required 須要長度

「412″ : Precondition Failed 條件失敗

「413″ : Request Entity Too Large 請求實體太大

「414″ : Request-URI Too Large 請求URI太長

「415″ : Unsupported Media Type 不支持媒體類型

「416″ : Requested range not satisfiable

「417″ : Expectation Failed

l  服務器錯誤

「500″ : Internal Server Error 服務器內部錯誤

「501″ : Not Implemented 未實現

「502″ : Bad Gateway 網關失敗

「503″ : Service Unavailable

「504″ : Gateway Time-out 網關超時

「505″ : HTTP Version not supported  HTTP版本不支持

HTTP狀態碼是可擴展的。HTTP應用程序不須要理解全部已註冊狀態碼的含義,儘管那樣的理解顯而易見是很合算的。可是,應用程序必須瞭解由第一位數字指定的狀態碼的類型,任何未被識別的響應應被看做是該類型的x00狀態,有一個例外就是未被識別的響應不能緩存。例如,若是客戶端收到一個未被識別的狀態碼431,則能夠安全的假定請求有錯,而且它會對待此響應就像它接收了一個狀態碼是400的響應。在這種狀況下,用戶代理(user agent)應當把實體和響應一塊兒提交給用戶,由於實體極可能包括人可讀的關於解釋不正常狀態的信息。報文最後是實體信息,即客戶請求獲得的HTTP服務器上的資源內容

 


 

常見的 content-type

這應該是最多見的 POST 提交數據的方式了。瀏覽器的原生 form 表單,若是不設置 enctype 屬性,那麼最終就會以 application/x-www-form-urlencoded 方式提交數據。請求相似於下面這樣(無關的請求頭在本文中都省略掉了): 

POST http://www.example.com HTTP/1.1 
Content-Type: application/x-www-form-urlencoded;charset=utf-8 

title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3 
首先,Content-Type 被指定爲 application/x-www-form-urlencoded;其次,提交的數據按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 都進行了 URL 轉碼。大部分服務端語言都對這種方式有很好的支持。例如 PHP 中,$_POST['title'] 能夠獲取到 title 的值,$_POST['sub'] 能夠獲得 sub 數組。 

不少時候,咱們用 Ajax 提交數據時,也是使用這種方式。例如 JQuery 和 QWrap 的 Ajax,Content-Type 默認值都是「application/x-www-form-urlencoded;charset=utf-8」。 

multipart/form-data 

這又是一個常見的 POST 數據提交的方式。咱們使用表單上傳文件時,必須讓 form 的 enctyped 等於這個值。直接來看一個請求示例: 

POST http://www.example.com HTTP/1.1 
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA 

------WebKitFormBoundaryrGKCBY7qhFd3TrwA 
Content-Disposition: form-data; name="text" 

title 
------WebKitFormBoundaryrGKCBY7qhFd3TrwA 
Content-Disposition: form-data; name="file"; filename="chrome.png" 
Content-Type: image/png 

PNG ... content of chrome.png ... 
------WebKitFormBoundaryrGKCBY7qhFd3TrwA-- 
這個例子稍微複雜點。首先生成了一個 boundary 用於分割不一樣的字段,爲了不與正文內容重複,boundary 很長很複雜。而後 Content-Type 裏指明瞭數據是以 mutipart/form-data 來編碼,本次請求的 boundary 是什麼內容。消息主體裏按照字段個數又分爲多個結構相似的部分,每部分都是以 --boundary 開始,緊接着內容描述信息,而後是回車,最後是字段具體內容(文本或二進制)。若是傳輸的是文件,還要包含文件名和文件類型信息。消息主體最後以 --boundary-- 標示結束。關於 mutipart/form-data 的詳細定義,請前往 rfc1867 查看。 

這種方式通常用來上傳文件,各大服務端語言對它也有着良好的支持。 

上面提到的這兩種 POST 數據的方式,都是瀏覽器原生支持的,並且現階段原生 form 表單也只支持這兩種方式。可是隨着愈來愈多的 Web 站點,尤爲是 WebApp,所有使用 Ajax 進行數據交互以後,咱們徹底能夠定義新的數據提交方式,給開發帶來更多便利。 

application/json 

application/json 這個 Content-Type 做爲響應頭你們確定不陌生。實際上,如今愈來愈多的人把它做爲請求頭,用來告訴服務端消息主體是序列化後的 JSON 字符串。因爲 JSON 規範的流行,除了低版本 IE 以外的各大瀏覽器都原生支持 JSON.stringify,服務端語言也都有處理 JSON 的函數,使用 JSON 不會趕上什麼麻煩。 

JSON 格式支持比鍵值對複雜得多的結構化數據,這一點也頗有用。記得我幾年前作一個項目時,須要提交的數據層次很是深,我就是把數據 JSON 序列化以後來提交的。不過當時我是把 JSON 字符串做爲 val,仍然放在鍵值對裏,以 x-www-form-urlencoded 方式提交。 

Google 的 AngularJS 中的 Ajax 功能,默認就是提交 JSON 字符串。例以下面這段代碼: 

var data = {'title':'test', 'sub' : [1,2,3]}; 
$http.post(url, data).success(function(result) { 
    ... 
}); 
最終發送的請求是: 

POST http://www.example.com HTTP/1.1 
Content-Type: application/json;charset=utf-8 

{"title":"test","sub":[1,2,3]} 
這種方案,能夠方便的提交複雜的結構化數據,特別適合 RESTful 的接口。各大抓包工具如 Chrome 自帶的開發者工具、Firebug、Fiddler,都會以樹形結構展現 JSON 數據,很是友好。但也有些服務端語言尚未支持這種方式,例如 php 就沒法經過 $_POST 對象從上面的請求中得到內容。這時候,須要本身動手處理下:在請求頭中 Content-Type 爲 application/json 時,從 php://input 裏得到原始輸入流,再 json_decode 成對象。一些 php 框架已經開始這麼作了。 

固然 AngularJS 也能夠配置爲使用 x-www-form-urlencoded 方式提交數據。若有須要,能夠參考這篇文章。 

text/xml 個人博客以前提到過 XML-RPC(XML Remote Procedure Call)。它是一種使用 HTTP 做爲傳輸協議,XML 做爲編碼方式的遠程調用規範。典型的 XML-RPC 請求是這樣的: POST http://www.example.com HTTP/1.1 Content-Type: text/xml <!--?xml version="1.0"?--> <methodcall>     <methodname>examples.getStateName</methodname>     <params>         <param>             <value><i4>41</i4></value>              </params> </methodcall> XML-RPC 協議簡單、功可以用,各類語言的實現都有。它的使用也很普遍,如 WordPress 的 XML-RPC Api,搜索引擎的 ping 服務等等。JavaScript 中,也有現成的庫支持以這種方式進行數據交互,能很好的支持已有的 XML-RPC 服務。不過,我我的以爲 XML 結構仍是過於臃腫,通常場景用 JSON 會更靈活方便。 

相關文章
相關標籤/搜索