Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 在线亚洲精品国产成人二区,国产综合精品,影视先锋av资源噜噜

          整合營(yíng)銷(xiāo)服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢(xún)熱線:

          3分鐘理解HTTP的請(qǐng)求與響應(yīng)

          3分鐘理解HTTP的請(qǐng)求與響應(yīng)

          TTP和HTTPS

          HTTP協(xié)議(HyperText Transfer Protocol,超文本傳輸協(xié)議):是一種發(fā)布和接收 HTML頁(yè)面的方法。

          HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)簡(jiǎn)單講是HTTP的安全版,在HTTP下加入SSL層。

          SSL(Secure Sockets Layer 安全套接層)主要用于Web的安全傳輸協(xié)議,在傳輸層對(duì)網(wǎng)絡(luò)連接進(jìn)行加密,保障在Internet上數(shù)據(jù)傳輸?shù)陌踩?/p>

          • HTTP的端口號(hào)為80,
          • HTTPS的端口號(hào)為443

          HTTP的請(qǐng)求與響應(yīng)

          HTTP通信由兩部分組成: 客戶(hù)端請(qǐng)求消息服務(wù)器響應(yīng)消息

          HTTP的請(qǐng)求與響應(yīng)

          瀏覽器發(fā)送HTTP請(qǐng)求的過(guò)程:

          1. 當(dāng)用戶(hù)在瀏覽器的地址欄中輸入一個(gè)URL并按回車(chē)鍵之后,瀏覽器會(huì)向HTTP服務(wù)器發(fā)送HTTP請(qǐng)求。HTTP請(qǐng)求主要分為“Get”和“Post”兩種方法。
          2. 當(dāng)我們?cè)跒g覽器輸入U(xiǎn)RL http://www.baidu.com 的時(shí)候,瀏覽器發(fā)送一個(gè)Request請(qǐng)求去獲取 http://www.baidu.com 的html文件,服務(wù)器把Response文件對(duì)象發(fā)送回給瀏覽器。
          3. 瀏覽器分析Response中的 HTML,發(fā)現(xiàn)其中引用了很多其他文件,比如Images文件,CSS文件,JS文件。 瀏覽器會(huì)自動(dòng)再次發(fā)送Request去獲取圖片,CSS文件,或者JS文件。
          4. 當(dāng)所有的文件都下載成功后,網(wǎng)頁(yè)會(huì)根據(jù)HTML語(yǔ)法結(jié)構(gòu),完整的顯示出來(lái)了。

          URL(Uniform / Universal Resource Locator的縮寫(xiě)):統(tǒng)一資源定位符,是用于完整地描述Internet上網(wǎng)頁(yè)和其他資源的地址的一種標(biāo)識(shí)方法。

          URL

          基本格式:scheme://host[:port#]/path/…/[?query-string][#anchor]

          • scheme:協(xié)議(例如:http, https, ftp)
          • host:服務(wù)器的IP地址或者域名
          • port#:服務(wù)器的端口(如果是走協(xié)議默認(rèn)端口,缺省端口80)
          • path:訪問(wèn)資源的路徑
          • query-string:參數(shù),發(fā)送給http服務(wù)器的數(shù)據(jù)
          • anchor:錨(跳轉(zhuǎn)到網(wǎng)頁(yè)的指定錨點(diǎn)位置)

          例如:

          • ftp://192.168.0.116:8080/index
          • http://www.baidu.com
          • http://item.jd.com/11936238.html#product-detail

          客戶(hù)端HTTP請(qǐng)求

          URL只是標(biāo)識(shí)資源的位置,而HTTP是用來(lái)提交和獲取資源??蛻?hù)端發(fā)送一個(gè)HTTP請(qǐng)求到服務(wù)器的請(qǐng)求消息,包括以下格式:

          請(qǐng)求行、請(qǐng)求頭部、空行、請(qǐng)求數(shù)據(jù)
          

          四個(gè)部分組成,下圖給出了請(qǐng)求報(bào)文的一般格式。

          請(qǐng)求報(bào)文的一般格式

          一個(gè)典型的HTTP請(qǐng)求示例:

          GET https://www.baidu.com/ HTTP/1.1
          Host: www.baidu.com
          Connection: keep-alive
          Upgrade-Insecure-Requests: 1
          User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
          Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
          Referer: http://www.baidu.com/
          Accept-Encoding: gzip, deflate, sdch, br
          Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
          Cookie: BAIDUI......
          

          請(qǐng)求方法

          GET https://www.baidu.com/ HTTP/1.1
          

          根據(jù)HTTP標(biāo)準(zhǔn),HTTP請(qǐng)求可以使用多種請(qǐng)求方法。

          HTTP 0.9:只有基本的文本 GET 功能。

          HTTP 1.0:完善的請(qǐng)求/響應(yīng)模型,并將協(xié)議補(bǔ)充完整,定義了三種請(qǐng)求方法: GET, POST 和 HEAD方法。

          HTTP 1.1:在 1.0 基礎(chǔ)上進(jìn)行更新,新增了五種請(qǐng)求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

          HTTP 2.0(未普及):請(qǐng)求/響應(yīng)首部的定義基本沒(méi)有改變,只是所有首部鍵必須全部小寫(xiě),而且請(qǐng)求行要獨(dú)立為 :method、:scheme、:host、:path這些鍵值對(duì)。

          請(qǐng)求方法

          HTTP請(qǐng)求主要分為Get和Post兩種方法

          • GET是從服務(wù)器上獲取數(shù)據(jù),POST是向服務(wù)器傳送數(shù)據(jù)
          • GET請(qǐng)求參數(shù)顯示,都顯示在瀏覽器網(wǎng)址上,HTTP服務(wù)器根據(jù)該請(qǐng)求所包含URL中的參數(shù)來(lái)產(chǎn)生響應(yīng)內(nèi)容,即“Get”請(qǐng)求的參數(shù)是URL的一部分。 例如: http://www.baidu.com/s?wd=Chinese
          • POST請(qǐng)求參數(shù)在請(qǐng)求體當(dāng)中,消息長(zhǎng)度沒(méi)有限制而且以隱式的方式進(jìn)行發(fā)送,通常用來(lái)向HTTP服務(wù)器提交量比較大的數(shù)據(jù)(比如請(qǐng)求中包含許多參數(shù)或者文件上傳操作等),請(qǐng)求的參數(shù)包含在“Content-Type”消息頭里,指明該消息體的媒體類(lèi)型和編碼,

          注意:避免使用Get方式提交表單,因?yàn)橛锌赡軙?huì)導(dǎo)致安全問(wèn)題。 比如說(shuō)在登陸表單中用Get方式,用戶(hù)輸入的用戶(hù)名和密碼將在地址欄中暴露無(wú)遺。

          常用的請(qǐng)求報(bào)頭

          1. Host (主機(jī)和端口號(hào))

          Host:對(duì)應(yīng)網(wǎng)址URL中的Web名稱(chēng)和端口號(hào),用于指定被請(qǐng)求資源的Internet主機(jī)和端口號(hào),通常屬于URL的一部分。

          2. Connection (鏈接類(lèi)型)

          Connection:表示客戶(hù)端與服務(wù)連接類(lèi)型

          1.Client 發(fā)起一個(gè)包含 Connection:keep-alive 的請(qǐng)求,HTTP/1.1使用 keep-alive 為默認(rèn)值。

          2.Server收到請(qǐng)求后:

          • 如果 Server 支持 keep-alive,回復(fù)一個(gè)包含 Connection:keep-alive 的響應(yīng),不關(guān)閉連接;
          • 如果 Server 不支持 keep-alive,回復(fù)一個(gè)包含 Connection:close 的響應(yīng),關(guān)閉連接。

          3.如果client收到包含 Connection:keep-alive 的響應(yīng),向同一個(gè)連接發(fā)送下一個(gè)請(qǐng)求,直到一方主動(dòng)關(guān)閉連接。

          keep-alive在很多情況下能夠重用連接,減少資源消耗,縮短響應(yīng)時(shí)間,比如當(dāng)瀏覽器需要多個(gè)文件時(shí)(比如一個(gè)HTML文件和相關(guān)的圖形文件),不需要每次都去請(qǐng)求建立連接。

          3. Upgrade-Insecure-Requests (升級(jí)為HTTPS請(qǐng)求)

          Upgrade-Insecure-Requests:升級(jí)不安全的請(qǐng)求,意思是會(huì)在加載 http 資源時(shí)自動(dòng)替換成 https 請(qǐng)求,讓瀏覽器不再顯示https頁(yè)面中的http請(qǐng)求警報(bào)。

          HTTPS 是以安全為目標(biāo)的 HTTP 通道,所以在 HTTPS 承載的頁(yè)面上不允許出現(xiàn) HTTP 請(qǐng)求,一旦出現(xiàn)就是提示或報(bào)錯(cuò)。

          4. User-Agent (瀏覽器名稱(chēng))

          User-Agent:是客戶(hù)瀏覽器的名稱(chēng),以后會(huì)詳細(xì)講。

          5. Accept (傳輸文件類(lèi)型)

          Accept:指瀏覽器或其他客戶(hù)端可以接受的MIME(Multipurpose Internet Mail Extensions(多用途互聯(lián)網(wǎng)郵件擴(kuò)展))文件類(lèi)型,服務(wù)器可以根據(jù)它判斷并返回適當(dāng)?shù)奈募袷健?/p>

          舉例:

          • Accept: */*:表示什么都可以接收。
          • Accept:image/gif:表明客戶(hù)端希望接受GIF圖像格式的資源;
          • Accept:text/html:表明客戶(hù)端希望接受html文本。
          • Accept: text/html, application/xhtml+xml;q=0.9, image/*;q=0.8:表示瀏覽器支持的 MIME 類(lèi)型分別是 html文本、xhtml和xml文檔、所有的圖像格式資源。

          6. Referer (頁(yè)面跳轉(zhuǎn)處)

          Referer:表明產(chǎn)生請(qǐng)求的網(wǎng)頁(yè)來(lái)自于哪個(gè)URL,用戶(hù)是從該 Referer頁(yè)面訪問(wèn)到當(dāng)前請(qǐng)求的頁(yè)面。這個(gè)屬性可以用來(lái)跟蹤Web請(qǐng)求來(lái)自哪個(gè)頁(yè)面,是從什么網(wǎng)站來(lái)的等。

          有時(shí)候遇到下載某網(wǎng)站圖片,需要對(duì)應(yīng)的referer,否則無(wú)法下載圖片,那是因?yàn)槿思易隽朔辣I鏈,原理就是根據(jù)referer去判斷是否是本網(wǎng)站的地址,如果不是,則拒絕,如果是,就可以下載;

          7. Accept-Encoding(文件編解碼格式)

          Accept-Encoding:指出瀏覽器可以接受的編碼方式。編碼方式不同于文件格式,它是為了壓縮文件并加速文件傳遞速度。瀏覽器在接收到Web響應(yīng)之后先解碼,然后再檢查文件格式,許多情形下這可以減少大量的下載時(shí)間。

          舉例:Accept-Encoding:gzip;q=1.0, identity; q=0.5, *;q=0

          如果有多個(gè)Encoding同時(shí)匹配, 按照q值順序排列,本例中按順序支持 gzip, identity壓縮編碼,支持gzip的瀏覽器會(huì)返回經(jīng)過(guò)gzip編碼的HTML頁(yè)面。 如果請(qǐng)求消息中沒(méi)有設(shè)置這個(gè)域服務(wù)器假定客戶(hù)端對(duì)各種內(nèi)容編碼都可以接受。

          8. Accept-Language(語(yǔ)言種類(lèi))

          Accept-Langeuage:指出瀏覽器可以接受的語(yǔ)言種類(lèi),如en或en-us指英語(yǔ),zh或者zh-cn指中文,當(dāng)服務(wù)器能夠提供一種以上的語(yǔ)言版本時(shí)要用到。

          9. Accept-Charset(字符編碼)

          Accept-Charset:指出瀏覽器可以接受的字符編碼。

          舉例:Accept-Charset:iso-8859-1,gb2312,utf-8

          • ISO8859-1:通常叫做Latin-1。Latin-1包括了書(shū)寫(xiě)所有西方歐洲語(yǔ)言不可缺少的附加字符,英文瀏覽器的默認(rèn)值是ISO-8859-1.
          • gb2312:標(biāo)準(zhǔn)簡(jiǎn)體中文字符集;
          • utf-8:UNICODE 的一種變長(zhǎng)字符編碼,可以解決多種語(yǔ)言文本顯示問(wèn)題,從而實(shí)現(xiàn)應(yīng)用國(guó)際化和本地化。

          如果在請(qǐng)求消息中沒(méi)有設(shè)置這個(gè)域,缺省是任何字符集都可以接受。

          10. Cookie (Cookie)

          Cookie:瀏覽器用這個(gè)屬性向服務(wù)器發(fā)送Cookie。Cookie是在瀏覽器中寄存的小型數(shù)據(jù)體,它可以記載和服務(wù)器相關(guān)的用戶(hù)信息,也可以用來(lái)實(shí)現(xiàn)會(huì)話功能,以后會(huì)詳細(xì)講。

          11. Content-Type (POST數(shù)據(jù)類(lèi)型)

          Content-Type:POST請(qǐng)求里用來(lái)表示的內(nèi)容類(lèi)型。

          舉例:Content-Type=Text/XML; charset=gb2312:

          指明該請(qǐng)求的消息體中包含的是純文本的XML類(lèi)型的數(shù)據(jù),字符編碼采用“gb2312”。

          服務(wù)端HTTP響應(yīng)

          HTTP響應(yīng)也由四個(gè)部分組成,分別是: 狀態(tài)行、消息報(bào)頭、空行、響應(yīng)正文

          HTTP響應(yīng)

          HTTP/1.1 200 OK
          Server: Tengine
          Connection: keep-alive
          Date: Wed, 30 Nov 2016 07:58:21 GMT
          Cache-Control: no-cache
          Content-Type: text/html;charset=UTF-8
          Keep-Alive: timeout=20
          Vary: Accept-Encoding
          Pragma: no-cache
          X-NWS-LOG-UUID: bd27210a-24e5-4740-8f6c-25dbafa9c395
          Content-Length: 180945
          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ....
          

          常用的響應(yīng)報(bào)頭

          理論上所有的響應(yīng)頭信息都應(yīng)該是回應(yīng)請(qǐng)求頭的。但是服務(wù)端為了效率,安全,還有其他方面的考慮,會(huì)添加相對(duì)應(yīng)的響應(yīng)頭信息,從上圖可以看到:

          1. Cache-Control:must-revalidate, no-cache, private。

          這個(gè)值告訴客戶(hù)端,服務(wù)端不希望客戶(hù)端緩存資源,在下次請(qǐng)求資源時(shí),必須要從新請(qǐng)求服務(wù)器,不能從緩存副本中獲取資源。

          • Cache-Control是響應(yīng)頭中很重要的信息,當(dāng)客戶(hù)端請(qǐng)求頭中包含Cache-Control:max-age=0請(qǐng)求,明確表示不會(huì)緩存服務(wù)器資源時(shí),Cache-Control作為作為回應(yīng)信息,通常會(huì)返回no-cache,意思就是說(shuō),"那就不緩存唄"。
          • 當(dāng)客戶(hù)端在請(qǐng)求頭中沒(méi)有包含Cache-Control時(shí),服務(wù)端往往會(huì)定,不同的資源不同的緩存策略,比如說(shuō)oschina在緩存圖片資源的策略就是Cache-Control:max-age=86400,這個(gè)意思是,從當(dāng)前時(shí)間開(kāi)始,在86400秒的時(shí)間內(nèi),客戶(hù)端可以直接從緩存副本中讀取資源,而不需要向服務(wù)器請(qǐng)求。

          2. Connection:keep-alive

          這個(gè)字段作為回應(yīng)客戶(hù)端的Connection:keep-alive,告訴客戶(hù)端服務(wù)器的tcp連接也是一個(gè)長(zhǎng)連接,客戶(hù)端可以繼續(xù)使用這個(gè)tcp連接發(fā)送http請(qǐng)求。

          3. Content-Encoding:gzip

          告訴客戶(hù)端,服務(wù)端發(fā)送的資源是采用gzip編碼的,客戶(hù)端看到這個(gè)信息后,應(yīng)該采用gzip對(duì)資源進(jìn)行解碼。

          4. Content-Type:text/html;charset=UTF-8

          告訴客戶(hù)端,資源文件的類(lèi)型,還有字符編碼,客戶(hù)端通過(guò)utf-8對(duì)資源進(jìn)行解碼,然后對(duì)資源進(jìn)行html解析。通常我們會(huì)看到有些網(wǎng)站是亂碼的,往往就是服務(wù)器端沒(méi)有返回正確的編碼。

          5. Date:Sun, 21 Sep 2016 06:18:21 GMT

          這個(gè)是服務(wù)端發(fā)送資源時(shí)的服務(wù)器時(shí)間,GMT是格林尼治所在地的標(biāo)準(zhǔn)時(shí)間。http協(xié)議中發(fā)送的時(shí)間都是GMT的,這主要是解決在互聯(lián)網(wǎng)上,不同時(shí)區(qū)在相互請(qǐng)求資源的時(shí)候,時(shí)間混亂問(wèn)題。

          6. Expires:Sun, 1 Jan 2000 01:00:00 GMT

          這個(gè)響應(yīng)頭也是跟緩存有關(guān)的,告訴客戶(hù)端在這個(gè)時(shí)間前,可以直接訪問(wèn)緩存副本,很顯然這個(gè)值會(huì)存在問(wèn)題,因?yàn)榭蛻?hù)端和服務(wù)器的時(shí)間不一定會(huì)都是相同的,如果時(shí)間不同就會(huì)導(dǎo)致問(wèn)題。所以這個(gè)響應(yīng)頭是沒(méi)有Cache-Control:max-age=*這個(gè)響應(yīng)頭準(zhǔn)確的,因?yàn)閙ax-age=date中的date是個(gè)相對(duì)時(shí)間,不僅更好理解,也更準(zhǔn)確。

          7. Pragma:no-cache

          這個(gè)含義與Cache-Control等同。

          8.Server:Tengine/1.4.6

          這個(gè)是服務(wù)器和相對(duì)應(yīng)的版本,只是告訴客戶(hù)端服務(wù)器的信息。

          9. Transfer-Encoding:chunked

          這個(gè)響應(yīng)頭告訴客戶(hù)端,服務(wù)器發(fā)送的資源的方式是分塊發(fā)送的。一般分塊發(fā)送的資源都是服務(wù)器動(dòng)態(tài)生成的,在發(fā)送時(shí)還不知道發(fā)送資源的大小,所以采用分塊發(fā)送,每一塊都是獨(dú)立的,獨(dú)立的塊都能標(biāo)示自己的長(zhǎng)度,最后一塊是0長(zhǎng)度的,當(dāng)客戶(hù)端讀到這個(gè)0長(zhǎng)度的塊時(shí),就可以確定資源已經(jīng)傳輸完了。

          10. Vary: Accept-Encoding

          告訴緩存服務(wù)器,緩存壓縮文件和非壓縮文件兩個(gè)版本,現(xiàn)在這個(gè)字段用處并不大,因?yàn)楝F(xiàn)在的瀏覽器都是支持壓縮的。

          Cookie 和 Session:

          服務(wù)器和客戶(hù)端的交互僅限于請(qǐng)求/響應(yīng)過(guò)程,結(jié)束之后便斷開(kāi),在下一次請(qǐng)求時(shí),服務(wù)器會(huì)認(rèn)為新的客戶(hù)端。

          為了維護(hù)他們之間的鏈接,讓服務(wù)器知道這是前一個(gè)用戶(hù)發(fā)送的請(qǐng)求,必須在一個(gè)地方保存客戶(hù)端的信息。

          • Cookie:通過(guò)在 客戶(hù)端 記錄的信息確定用戶(hù)的身份。
          • Session:通過(guò)在 服務(wù)器端 記錄的信息確定用戶(hù)的身份。

          響應(yīng)狀態(tài)碼

          響應(yīng)狀態(tài)代碼有三位數(shù)字組成,第一個(gè)數(shù)字定義了響應(yīng)的類(lèi)別,且有五種可能取值。

          常見(jiàn)狀態(tài)碼:

          • 100~199:表示服務(wù)器成功接收部分請(qǐng)求,要求客戶(hù)端繼續(xù)提交其余請(qǐng)求才能完成整個(gè)處理過(guò)程。
          • 200~299:表示服務(wù)器成功接收請(qǐng)求并已完成整個(gè)處理過(guò)程。常用200(OK 請(qǐng)求成功)。
          • 300~399:為完成請(qǐng)求,客戶(hù)需進(jìn)一步細(xì)化請(qǐng)求。例如:請(qǐng)求的資源已經(jīng)移動(dòng)一個(gè)新地址、常用302(所請(qǐng)求的頁(yè)面已經(jīng)臨時(shí)轉(zhuǎn)移至新的url)、307和304(使用緩存資源)。
          • 400~499:客戶(hù)端的請(qǐng)求有錯(cuò)誤,常用404(服務(wù)器無(wú)法找到被請(qǐng)求的頁(yè)面)、403(服務(wù)器拒絕訪問(wèn),權(quán)限不夠)。
          • 500~599:服務(wù)器端出現(xiàn)錯(cuò)誤,常用500(請(qǐng)求未完成。服務(wù)器遇到不可預(yù)知的情況)。

          、HTTP 響應(yīng)報(bào)文結(jié)構(gòu)

          前面幾篇教程我們了解了如何在 Go 語(yǔ)言中解析用戶(hù)請(qǐng)求信息,包括表單字段和文件上傳,接下來(lái),我們來(lái)看看處理完請(qǐng)求后,如何將響應(yīng)發(fā)送給客戶(hù)端。HTTP 響應(yīng)的報(bào)文結(jié)構(gòu)如下所示:

          HTTP 響應(yīng)報(bào)文結(jié)構(gòu)

          和 HTTP 請(qǐng)求報(bào)文結(jié)構(gòu)類(lèi)似,響應(yīng)報(bào)文也可以分為三部分:狀態(tài)行、響應(yīng)頭(首部字段)和響應(yīng)主體。

          首先是狀態(tài)行,在狀態(tài)行中包含了 HTTP 協(xié)議版本和響應(yīng)狀態(tài)碼,200 OK 表示響應(yīng)成功,更多狀態(tài)碼信息(常見(jiàn)的有 404、403、500、301 等)可以網(wǎng)上查看下 HTTP 協(xié)議或者閱讀 HTTP 響應(yīng)狀態(tài)碼這篇文章了解。

          然后是響應(yīng)頭,其中包含了 HTTP 響應(yīng)的首部字段,比如內(nèi)容類(lèi)型/編碼、緩存控制、Cookie 信息等。

          最后是響應(yīng)實(shí)體,對(duì)于 API 接口來(lái)說(shuō),通常就是返回的 XML/JSON 格式數(shù)據(jù),對(duì)于 HTML 視圖響應(yīng),就是一個(gè)標(biāo)準(zhǔn)的 HTML 文檔,如上圖所示。響應(yīng)頭和響應(yīng)報(bào)文之間通過(guò)兩個(gè)換行符分隔。

          2、ResponseWriter 接口

          在 Go 語(yǔ)言中,客戶(hù)端請(qǐng)求信息都封裝到了 Request 對(duì)象,但是發(fā)送給客戶(hù)端的響應(yīng)并不是 Response 對(duì)象,而是 ResponseWriter:

          func Home(w http.ResponseWriter, r *http.Request)  {
              io.WriteString(w, "Welcome to my blog site")
          }
          

          ResponseWriter 是處理器用來(lái)創(chuàng)建 HTTP 響應(yīng)的接口,其源碼結(jié)構(gòu)如下所示:

          type ResponseWriter interface {
             // 用于設(shè)置/獲取所有響應(yīng)頭信息
              Header() Header
             // 用于寫(xiě)入數(shù)據(jù)到響應(yīng)實(shí)體
              Write([]byte) (int, error)
             // 用于設(shè)置響應(yīng)狀態(tài)碼
              WriteHeader(statusCode int)
          }
          

          實(shí)際上,在底層支撐 ResponseWriter 的結(jié)構(gòu)體就是 http.response,詳見(jiàn) net/http 包下 server.go 中的 readRequest 方法(調(diào)用處理器處理 HTTP 請(qǐng)求時(shí)調(diào)用了該方法返回響應(yīng)對(duì)象),并且其返回值是 response 指針,這也是為什么在處理器方法聲明的時(shí)候 Request 是指針類(lèi)型,而 ResponseWriter 不是,實(shí)際上在底層,響應(yīng)對(duì)象也是指針類(lèi)型(因?yàn)樵趹?yīng)用代碼中需要設(shè)置響應(yīng)頭和響應(yīng)實(shí)體,所以響應(yīng)對(duì)象理應(yīng)是指針類(lèi)型):

          func (c *conn) readRequest(ctx context.Context) (w *response, err error) {
              ...
              w = &response{
                  conn:          c,
                  cancelCtx:     cancelCtx,
                  req:           req,
                  reqBody:       req.Body,
                  handlerHeader: make(Header),
                  contentLength: -1,
                  closeNotifyCh: make(chan bool, 1),
                  wants10KeepAlive: req.wantsHttp10KeepAlive(),
                  wantsClose:       req.wantsClose(),
              }
              if isH2Upgrade {
                  w.closeAfterReply = true
              }
              w.cw.res = w
              w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize)
              return w, nil
          }
          

          response 結(jié)構(gòu)體定義和 ResponseWriter 一樣都位于 server.go,感興趣的同學(xué)可以去看下源碼,不過(guò)由于 response 對(duì)外不可見(jiàn),所以只能通過(guò) ResponseWriter 接口訪問(wèn)它。兩者之間的關(guān)系是 ResponseWriter 是一個(gè)接口,而 http.response 實(shí)現(xiàn)了它。當(dāng)我們引用 ResponseWriter 時(shí),實(shí)際上引用的是 http.response 對(duì)象實(shí)例。

          3、設(shè)置響應(yīng)狀態(tài)碼

          如上面的 ResponseWriter 接口定義源碼所示,它包含三個(gè)方法:

          • WriteHeader
          • Header
          • Write

          WriteHeader 這個(gè)方法名有點(diǎn)誤導(dǎo),其實(shí)它并不是用來(lái)設(shè)置響應(yīng)頭的,該方法支持傳入一個(gè)整型數(shù)據(jù)用來(lái)表示響應(yīng)狀態(tài)碼,如果不調(diào)用該方法的話,默認(rèn)響應(yīng)狀態(tài)碼是 200 OK。

          WriteHeader 的主要作用是在 API 接口中返回錯(cuò)誤碼,我們?cè)?goblog/handlers/common.go 中新增一個(gè)處理器方法 Error,并通過(guò) w.WriteHeader 返回一個(gè) 401 未認(rèn)證狀態(tài)碼(注意在運(yùn)行時(shí) w 代表的是對(duì)應(yīng)的 response 對(duì)象實(shí)例,而不是接口):

          func Error(w http.ResponseWriter, r *http.Request)  {
              w.WriteHeader(401)
              fmt.Fprintln(w, "認(rèn)證后才能訪問(wèn)該接口")
          }
          

          注:這里通過(guò) fmt.Fprintln 將文本字符串寫(xiě)入響應(yīng)對(duì)象。

          然后在 routes/web.go 中添加一個(gè)路由與之映射:

          WebRoute{
              "ApiError",
              "GET",
              "/error",
              handlers.Error,
          },
          

          重啟 HTTP 服務(wù)器,通過(guò) curl 訪問(wèn) http://localhost:8080/error,返回的完整響應(yīng)報(bào)文如下:

          可以看到響應(yīng)狀態(tài)碼是 401 Unauthorized,表示該接口需要認(rèn)證后才能訪問(wèn)。這里,我們?cè)谶\(yùn)行 curl 時(shí)帶上 -i 選項(xiàng),以便可以看到完整的響應(yīng)報(bào)文,第一行是響應(yīng)狀態(tài)行,然后是響應(yīng)頭信息,響應(yīng)頭每一行是一個(gè)鍵值對(duì)映射,通過(guò)冒號(hào)分隔,左側(cè)是字段名,右側(cè)是字段值,最后是響應(yīng)實(shí)體,也就是我們?cè)诖a中寫(xiě)入的響應(yīng)數(shù)據(jù),響應(yīng)實(shí)體和響應(yīng)頭之間通過(guò)一個(gè)空行分隔(兩個(gè)換行符)。

          5、設(shè)置響應(yīng)頭

          Header 方法用于設(shè)置響應(yīng)頭信息,我們可以通過(guò) w.Header().Set 方法設(shè)置響應(yīng)頭(w.Header() 方法返回的是 Header 響應(yīng)頭對(duì)象,它和請(qǐng)求頭共用一個(gè)結(jié)構(gòu)體,因此請(qǐng)求頭上支持的方法這里都支持,比如可以通過(guò) w.Header().Add 方法新增響應(yīng)頭),這里我們?cè)O(shè)置一個(gè) 301 重定向響應(yīng),只需要通過(guò) w.WriteHeader 方法將響應(yīng)狀態(tài)碼設(shè)置為 301,再通過(guò) w.Header().Set 方法將負(fù)責(zé)重定向的響應(yīng)頭 Location 設(shè)置為一個(gè)可訪問(wèn)域名即可。

          在 goblog/handlers/common.go 中新建一個(gè)處理器方法 Redirect,在其中編寫(xiě)重定向?qū)崿F(xiàn)代碼如下:

          func Redirect(w http.ResponseWriter, r *http.Request)  {
              // 設(shè)置一個(gè) 301 重定向
              w.Header().Set("Location", "https://xueyuanjun.com")
              w.WriteHeader(301)
          }
          

          對(duì)于重定向請(qǐng)求,無(wú)需設(shè)置響應(yīng)實(shí)體,另外需要注意的是 w.Header().Set 必須在 w.WriteHeader 之前調(diào)用,因?yàn)橐坏┱{(diào)用 w.WriteHeader 之后,就不能對(duì)響應(yīng)頭進(jìn)行設(shè)置了。

          接下來(lái),在 routes/web.go 中注冊(cè)對(duì)應(yīng)的重定向路由:

          WebRoute{
              "Redirect",
              "GET",
              "/redirect",
              handlers.Redirect,
          },
          

          重啟 HTTP 服務(wù)器,通過(guò) curl 訪問(wèn)該路由可以清楚看到響應(yīng)被重定向,并且響應(yīng)實(shí)體為空:

          如果是在瀏覽器中訪問(wèn)的話,頁(yè)面就會(huì)跳轉(zhuǎn)到 https://xueyuanjun.com:

          6、寫(xiě)入數(shù)據(jù)到響應(yīng)實(shí)體

          Write 方法用于寫(xiě)入數(shù)據(jù)到 HTTP 響應(yīng)實(shí)體,如果調(diào)用 Write 方法時(shí)還不知道 Content-Type,會(huì)通過(guò)數(shù)據(jù)的前 512 個(gè)字節(jié)進(jìn)行判斷。

          返回文本字符串

          以 goblog/handlers/common.go 中定義的 Home 處理器方法為例,我們可以通過(guò) w.Write 寫(xiě)入一段歡迎文本到響應(yīng)實(shí)體:

          func Home(w http.ResponseWriter, r *http.Request)  {
              w.Write([]byte("歡迎訪問(wèn)學(xué)院君個(gè)人網(wǎng)站"));
          }
          

          由于 Write 方法接受的參數(shù)類(lèi)型是 []byte 切片,所以需要將字符串轉(zhuǎn)換為字節(jié)切片類(lèi)型。啟動(dòng) HTTP 服務(wù)器,通過(guò) curl 訪問(wèn)首頁(yè),就可以看到返回的文本信息了:

          返回 HTML 文檔

          如果要返回 HTML 文檔,可以這么寫(xiě)入響應(yīng)數(shù)據(jù):

          func Home(w http.ResponseWriter, r *http.Request)  {
              //w.Write([]byte("歡迎訪問(wèn)學(xué)院君個(gè)人網(wǎng)站"));
              html := `<html> 
                  <head>
                      <title>學(xué)院君個(gè)人網(wǎng)站</title>
                  </head> 
                  <body>
                      <h1>歡迎訪問(wèn)學(xué)院君個(gè)人網(wǎng)站</h1>
                  </body> 
              </html>`
              w.Write([]byte(html))
          }
          

          當(dāng)然,后面介紹視圖模板后,可以通過(guò)視圖模板渲染 HTML 文檔,這里我們先通過(guò)一個(gè)簡(jiǎn)單的包含 HTML 文檔信息的字符串替代,重啟 HTTP 服務(wù)器,通過(guò)瀏覽器訪問(wèn),就可以看到對(duì)應(yīng)的 HTML 視圖了:

          此外,由于響應(yīng)數(shù)據(jù)的內(nèi)容類(lèi)型變成了 HTML,在響應(yīng)頭中,也可以看到 Content-Type 也自動(dòng)調(diào)整成了 text/html,不再是純文本格式。這里的 Content-Type 就是根據(jù)傳入的數(shù)據(jù)自行判斷出來(lái)的。

          返回 JSON 格式數(shù)據(jù)

          當(dāng)然,我們也可以返回 JSON 格式數(shù)據(jù):

          type Greeting struct {
              Message string `json:"message"`
          }
          func Home(w http.ResponseWriter, r *http.Request)  {
              // 返回文本字符串
              //w.Write([]byte("歡迎訪問(wèn)學(xué)院君個(gè)人網(wǎng)站"));
              // 返回 HTML 文檔
              /*html := `<html>
                  <head>
                      <title>學(xué)院君個(gè)人網(wǎng)站</title>
                  </head> 
                  <body>
                      <h1>歡迎訪問(wèn)學(xué)院君個(gè)人網(wǎng)站</h1>
                  </body> 
              </html>`
              w.Write([]byte(html))*/
              // 返回 JSON 格式數(shù)據(jù)
              greeting := Greeting{
                  "歡迎訪問(wèn)學(xué)院君個(gè)人網(wǎng)站",
              }
              message, _ := json.Marshal(greeting)
              w.Write(message)
          }
          

          重啟 HTTP 服務(wù)器,在瀏覽器中訪問(wèn) http://localhost:8080:

          雖然返回的確實(shí)是合法的 JSON 格式數(shù)據(jù),但是內(nèi)容類(lèi)型依然是 text/plain,而不是 application/json,要返回這個(gè)格式的響應(yīng)頭,需要設(shè)置響應(yīng)頭才能實(shí)現(xiàn):

          // 返回 JSON 格式數(shù)據(jù)
          greeting := Greeting{
              "歡迎訪問(wèn)學(xué)院君個(gè)人網(wǎng)站",
          }
          message, _ := json.Marshal(greeting)
          w.Header().Set("Content-Type", "application/json")
          w.Write(message)
          

          重啟 HTTP 服務(wù)器,并再次通過(guò) curl 訪問(wèn)首頁(yè),就可以看到內(nèi)容類(lèi)型變成 application/json 了:

          (全文完)

          . HTTP請(qǐng)求格式

          做過(guò)Socket編程的人都知道,當(dāng)我們?cè)O(shè)計(jì)一個(gè)通信協(xié)議時(shí),“消息頭/消息體”的分割方式是很常用的,消息頭告訴對(duì)方這個(gè)消息是干什么的,消息體告訴對(duì) 方怎么干。HTTP協(xié)議傳輸?shù)南⒁彩沁@樣規(guī)定的,每一個(gè)HTTP包都分為HTTP頭和HTTP體兩部分,消息體是可選的,而消息頭是必須的。每當(dāng)我們打 開(kāi)一個(gè)網(wǎng)頁(yè),在上面點(diǎn)擊右鍵,選擇“查看源文件”,這時(shí)看到的HTML代碼就是HTTP的消息體,那么消息頭可以通過(guò)瀏覽器的開(kāi)發(fā)工具或者插件可以看到, 如果火狐的Firebug,IE的Httpwatch。

          客戶(hù)端通過(guò)發(fā)送 HTTP 請(qǐng)求向服務(wù)器請(qǐng)求對(duì)資源的訪問(wèn)。 它向服務(wù)器傳遞了一個(gè)數(shù)據(jù)塊,也就是請(qǐng)求信息,HTTP 請(qǐng)求由三部分組成:請(qǐng)求行、 請(qǐng)求頭和請(qǐng)求正文。

          請(qǐng)求行:請(qǐng)求方法 URI 協(xié)議/版本

          請(qǐng)求頭(Request Header)

          請(qǐng)求正文

          下面是一個(gè)HTTP請(qǐng)求的數(shù)據(jù):

          POST /index.php HTTP/1.1

          Host: localhost

          User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2

          Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

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

          Accept-Encoding: gzip, deflate

          Connection: keep-alive

          Referer: http://localhost/

          Content-Length:25

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

          username=aa&password=1234

          1、請(qǐng)求行:請(qǐng)求方法URI協(xié)議/版本

          請(qǐng)求的第一行是“方法 URL 協(xié)議/版本”,并以 回車(chē)換行作為結(jié)尾。請(qǐng)求行以空格分隔。格式如下:

          POST /index.php HTTP/1.1

          以上代碼中“GET”代表請(qǐng)求方法,“//ndex.php”表示URI,“HTTP/1.1代表協(xié)議和協(xié)議的版本。

          根據(jù)HTTP標(biāo)準(zhǔn),HTTP請(qǐng)求可以使用多種請(qǐng)求方法。例如:HTTP1.1支持7種請(qǐng)求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。在Internet應(yīng)用中,最常用的方法是GET和POST。

          URL完整地指定了要訪問(wèn)的網(wǎng)絡(luò)資源,通常只要給出相對(duì)于服務(wù)器的根目錄的相對(duì)目錄即可,因此總是以“/”開(kāi)頭,最后,協(xié)議版本聲明了通信過(guò)程中使用HTTP的版本。

          請(qǐng)求方法

          在 HTTP 協(xié)議中,HTTP 請(qǐng)求可以使用多種請(qǐng)求方法,這些方法指明了要以何種方式來(lái)訪問(wèn) Request-URI 所標(biāo)識(shí)的資源。HTTP1.1 支持的請(qǐng)求方法如下表所示:

          HTTP1.1 中的請(qǐng)求方式:

          方法

          作用

          GET

          請(qǐng)求獲取由 Request-URI 所標(biāo)識(shí)的資源

          POST

          請(qǐng)求服務(wù)器接收在請(qǐng)求中封裝的實(shí)體,并將其作為由 Request-Line 中的 Request-URI 所標(biāo)識(shí)的資源的一部分

          HEAD

          請(qǐng)求獲取由 Request-URI 所標(biāo)識(shí)的資源的響應(yīng)消息報(bào)頭

          PUT

          請(qǐng)求服務(wù)器存儲(chǔ)一個(gè)資源,并用 Request-URI 作為其標(biāo)識(shí)符

          DELETE

          請(qǐng)求服務(wù)器刪除由 Request-URI 所標(biāo)識(shí)的資源

          TRACE

          請(qǐng)求服務(wù)器回送到的請(qǐng)求信息,主要用于測(cè)試或診斷

          CONNECT

          保留將來(lái)使用

          OPTIONS

          請(qǐng)求查詢(xún)服務(wù)器的性能,或者查詢(xún)與資源相關(guān)的選項(xiàng)和需求

          重點(diǎn)介紹 GET、POST 和 HEAD 三個(gè)方法:

          (1)GET

          GET 方法用于獲取由 Request-URI 所標(biāo)識(shí)的資源的信息,常見(jiàn)的形式是:

          GET Request-URI HTTP/1.1

          GET方法是默認(rèn)的HTTP請(qǐng)求方法,例如當(dāng)我們通過(guò)在瀏覽器的地址欄中直接輸入網(wǎng)址的方式去訪問(wèn)網(wǎng)頁(yè)的時(shí)候,瀏覽器采用的就是 GET 方法向服務(wù)器獲取資源。

          我們可以使用GET方法來(lái)提交表單數(shù)據(jù),用GET方法提交的表單數(shù)據(jù)只經(jīng)過(guò)了簡(jiǎn)單的編碼,同時(shí)它將作為URL的一部分向服務(wù)器發(fā)送,因此,如果使用GET方法來(lái)提交表單數(shù)據(jù)就存在著安全隱患上。例如:

          Http://localhost/login.php?username=aa&password=1234

          從上面的URL請(qǐng)求中,很容易就可以辯認(rèn)出表單提交的內(nèi)容。(?之后的內(nèi)容)另外由于GET方法提交的數(shù)據(jù)是作為URL請(qǐng)求的一部分所以提交的數(shù)據(jù)量不能太大。這是因?yàn)闉g覽器對(duì)url的長(zhǎng)度有限制

          各種瀏覽器也會(huì)對(duì)url的長(zhǎng)度有所限制,下面是幾種常見(jiàn)瀏覽器的url長(zhǎng)度限制:(單位:字符)

          IE : 2803

          Firefox:65536

          Chrome:8182

          Safari:80000

          Opera:190000

          (2)POST

          POST方法是GET方法的一個(gè)替代方法,它主要是向Web服務(wù)器提交表單數(shù)據(jù),尤其是大批量的數(shù)據(jù)。 在請(qǐng)求頭信息結(jié)束之后的兩個(gè)回車(chē)換行之后(實(shí)際是空一行),就是表單提交的數(shù)據(jù)。如上面提到的post表單數(shù)據(jù):

          username=aa&password=1234

          POST方法克服了GET方法的一些缺點(diǎn)。通過(guò)POST方法提交表單數(shù)據(jù)時(shí),數(shù)據(jù)不是作為URL請(qǐng)求的一部分而是作為標(biāo)準(zhǔn)數(shù)據(jù)傳送給Web服務(wù)器,這就克 服了GET方法中的信息無(wú)法保密和數(shù)據(jù)量太小的缺點(diǎn)。因此,出于安全的考慮以及對(duì)用戶(hù)隱私的尊重,通常表單提交時(shí)采用POST方法。

            從編程的角度來(lái)講,如果用戶(hù)通過(guò)GET方法提交數(shù)據(jù),則數(shù)據(jù)存放在QUERY_STRING環(huán)境變量中,而POST方法提交的數(shù)據(jù)則可以從標(biāo)準(zhǔn)輸入流中獲取。

          GET與POST方法有以下區(qū)別:

          1、 在客戶(hù)端,Get方式在通過(guò)URL提交數(shù)據(jù),數(shù)據(jù)在URL中可以看到;POST方式,數(shù)據(jù)放在HTTP包的body中。

          2、 GET方式提交的數(shù)據(jù)大小有限制(因?yàn)闉g覽器對(duì)URL的長(zhǎng)度有限制),而POST則沒(méi)有此限制。

          3、安全性問(wèn)題。正如在(1)中提到,使用 Get 的時(shí)候,參數(shù)會(huì)顯示在地址欄上,而 Post 不會(huì)。所以,如果這些數(shù)據(jù)是中文數(shù)據(jù)而且是非敏感數(shù)據(jù),那么使用 get;如果用戶(hù)輸入的數(shù)據(jù)不是中文字符而且包含敏感數(shù)據(jù),那么還是使用 post為好。

          4.、服務(wù)器取值方式不一樣。GET方式取值,如php可以使用$_GET來(lái)取得變量的值,而POST方式通過(guò)$_POST來(lái)獲取變量的值。

          (3)HEAD

          HEAD 方法與 GET 方法幾乎是相同的,它們的區(qū)別在于 HEAD 方法只是請(qǐng)求消息報(bào)頭,而不是完整的內(nèi)容。對(duì)于 HEAD 請(qǐng)求的回應(yīng)部分來(lái)說(shuō),它的 HTTP 頭部中包含的信息與通過(guò) GET 請(qǐng)求所得到的信息是相同的。利用這個(gè)方法,不必傳輸整個(gè)資源內(nèi)容,就可以得到 Request-URI 所標(biāo)識(shí)的資源的信息。這個(gè)方法通常被用于測(cè)試超鏈接的有效性,是否可以訪問(wèn),以及最近是否更新。

          要注意的是,在 HTML 文檔中,書(shū)寫(xiě) get 和 post,大小寫(xiě)都可以,但在 HTTP 協(xié)議中的 GET 和 POST 只能是大寫(xiě)形式。

          2. 請(qǐng)求頭

          每個(gè)頭域由一個(gè)域名,冒號(hào)(:)和域值三部分組成。域名是大小寫(xiě)無(wú)關(guān)的,域值前可以添加任何數(shù)量的空格符,頭域可以被擴(kuò)展為多行,在每行開(kāi)始處,使用至少一個(gè)空格或制表符。

          HTTP最常見(jiàn)的請(qǐng)求頭如下:

          Transport 頭域

          Connection:

          作用:表示是否需要持久連接。

          如果服務(wù)器看到這里的值為“Keep-Alive”,或者看到請(qǐng)求使用的是HTTP 1.1(HTTP 1.1默認(rèn)進(jìn)行持久連接),它就可以利用持久連接的優(yōu)點(diǎn),當(dāng)頁(yè)面包含多個(gè)元素時(shí)(例如Applet,圖片),顯著地減少下載所需要的時(shí)間。要實(shí)現(xiàn)這一點(diǎn),服務(wù)器需要在應(yīng)答中發(fā)送一個(gè)Content-Length頭,最簡(jiǎn)單的實(shí)現(xiàn)方法是:先把內(nèi)容寫(xiě)入 ByteArrayOutputStream,然后在正式寫(xiě)出內(nèi)容之前計(jì)算它的大?。?/p>

          例如: Connection: keep-alive 當(dāng)一個(gè)網(wǎng)頁(yè)打開(kāi)完成后,客戶(hù)端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接不會(huì)關(guān)閉,如果客戶(hù)端再次訪問(wèn)這個(gè)服務(wù)器上的 網(wǎng)頁(yè),會(huì)繼續(xù)使用這一條已經(jīng)建立的連接

          例如: Connection: close 代表一個(gè)Request完成后,客戶(hù)端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接會(huì)關(guān)閉, 當(dāng)客戶(hù)端再次發(fā)送Request,需要重新建立TCP連接。

          Host(發(fā)送請(qǐng)求時(shí),該報(bào)頭域是必需的)

          Host請(qǐng)求報(bào)頭域主要用于指定被請(qǐng)求資源的Internet主機(jī)和端口號(hào),它通常從HTTP URL中提取出來(lái)的。

          eg:http://;localhost/index.html

          瀏覽器發(fā)送的請(qǐng)求消息中,就會(huì)包含Host請(qǐng)求報(bào)頭域,如下:

          Host:localhost

          此處使用缺省端口號(hào)80,若指定了端口號(hào)8080,則變成:Host:localhost:8080

          Client 頭域

          Accept:

          作用:瀏覽器可以接受的媒體類(lèi)型(MIME類(lèi)型),

          例如: Accept: text/html 代表瀏覽器可以接受服務(wù)器回發(fā)的類(lèi)型為 text/html 也就是我們常說(shuō)的html文檔, 如果服務(wù)器無(wú)法返回text/html類(lèi)型的數(shù)據(jù),服務(wù)器應(yīng)該返回一個(gè)406錯(cuò)誤(non acceptable)。

          通配符 * 代表任意類(lèi)型。例如 Accept: */* 代表瀏覽器可以處理所有類(lèi)型,(一般瀏覽器發(fā)給服務(wù)器都是發(fā)這個(gè))

          Accept-Encoding:

          作用: 瀏覽器申明自己接收的編碼方法,通常指定壓縮方法,是否支持壓縮,支持什么壓縮方法(gzip,deflate),(注意:這不是只字符編碼);

          例如: Accept-Encoding: gzip, deflate。Server能夠向支持gzip/deflate的瀏覽器返回經(jīng)gzip或者deflate編碼的HTML頁(yè)面。 許多情形下這可以減少5到10倍的下載時(shí)間,也節(jié)省帶寬。

          Accept-Language:

          作用: 瀏覽器申明自己接收的語(yǔ)言。

          語(yǔ)言跟字符集的區(qū)別:中文是語(yǔ)言,中文有多種字符集,比如big5,gb2312,gbk等等;

          例如: Accept-Language:zh-cn 。如果請(qǐng)求消息中沒(méi)有設(shè)置這個(gè)報(bào)頭域,服務(wù)器假定客戶(hù)端對(duì)各種語(yǔ)言都可以接受。

          User-Agent:

          作用:告訴HTTP服務(wù)器, 客戶(hù)端使用的操作系統(tǒng)和瀏覽器的名稱(chēng)和版本.

          我們上網(wǎng)登陸論壇的時(shí)候,往往會(huì)看到一些歡迎信息,其中列出了你的操作系統(tǒng)的名稱(chēng)和版本,你所使用的瀏覽器的名稱(chēng)和版本,這往往讓很多人感到很神 奇,實(shí)際上, 服務(wù)器應(yīng)用程序就是從User-Agent這個(gè)請(qǐng)求報(bào)頭域中獲取到這些信息User-Agent請(qǐng)求報(bào)頭域允許客戶(hù)端將它的操作系統(tǒng)、瀏覽 器和其它屬性告訴服務(wù)器。

          例如: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; InfoPath.2; .NET4.0E)

          Accept-Charset:

          作用:瀏覽器申明自己接收的字符集,這就是本文前面介紹的各種字符集和字符編碼,如gb2312,utf-8(通常我們說(shuō)Charset包括了相應(yīng)的字符編碼方案);

          例如:Accept-Charset:iso-8859-1,gb2312.如果在請(qǐng)求消息中沒(méi)有設(shè)置這個(gè)域,缺省是任何字符集都可以接受。

          Authorization:授權(quán)信息,通常出現(xiàn)在對(duì)服務(wù)器發(fā)送的WWW-Authenticate頭的應(yīng)答中;

          Authorization請(qǐng)求報(bào)頭域主要用于證明客戶(hù)端有權(quán)查看某個(gè)資源。當(dāng)瀏覽器訪問(wèn)一個(gè)頁(yè)面時(shí),如果收到服務(wù)器的響應(yīng)代碼為401(未授權(quán)),可以發(fā)送一個(gè)包含Authorization請(qǐng)求報(bào)頭域的請(qǐng)求,要求服務(wù)器對(duì)其進(jìn)行驗(yàn)證。

          Cookie/Login 頭域

          Cookie:

          作用: 最重要的header, 將cookie的值發(fā)送給HTTP 服務(wù)器

          Entity頭域

          Content-Length

          作用:發(fā)送給HTTP服務(wù)器數(shù)據(jù)的長(zhǎng)度。即請(qǐng)求消息正文的長(zhǎng)度;

          例如: Content-Length: 38

          Content-Type:

          作用:

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

          Miscellaneous 頭域

          Referer:

          作用: 提供了Request的上下文信息的服務(wù)器,告訴服務(wù)器我是從哪個(gè)鏈接過(guò)來(lái)的,比如從我主頁(yè)上鏈接到一個(gè)朋友那里, 他的服務(wù)器就能夠從HTTP Referer中統(tǒng)計(jì)出每天有多少用戶(hù)點(diǎn)擊我主頁(yè)上的鏈接訪問(wèn) 他的網(wǎng)站。

          例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT

          Cache 頭域

          If-Modified-Since:

          作用: 把瀏覽器端緩存頁(yè)面的最后修改時(shí)間發(fā)送到服務(wù)器去,服務(wù)器會(huì)把這個(gè)時(shí)間與服務(wù)器上實(shí)際文件的最后修改時(shí)間進(jìn)行對(duì)比。如果時(shí)間一致,那么返回304,客戶(hù)端 就直接使用本地緩存文件。如果時(shí)間不一致,就會(huì)返回200和新的文件內(nèi)容??蛻?hù)端接到之后,會(huì)丟棄舊文件,把新文件緩存起來(lái),并顯示在瀏覽器中。

          例如:If-Modified-Since: Thu, 09 Feb 2012 09:07:57 GMT。

          If-None-Match:

          作用: If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETag信息。 當(dāng)用戶(hù)再次請(qǐng)求該資源時(shí),將在HTTP Request 中加入If-None-Match信息(ETag的值)。如果服務(wù)器驗(yàn)證資源的ETag沒(méi)有改變(該資源沒(méi)有更新),將返回一個(gè)304狀態(tài)告訴客戶(hù)端使用 本地緩存文件。否則將返回200狀態(tài)和新的資源和Etag. 使用這樣的機(jī)制將提高網(wǎng)站的性能

          例如: If-None-Match: "03f2b33c0bfcc1:0"

          Pragma:

          作用: 防止頁(yè)面被緩存, 在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一樣

          Pargma只有一個(gè)用法, 例如: Pragma: no-cache

          注意: 在HTTP/1.0版本中,只實(shí)現(xiàn)了Pragema:no-cache, 沒(méi)有實(shí)現(xiàn)Cache-Control

          Cache-Control:

          作用: 這個(gè)是非常重要的規(guī)則。 這個(gè)用來(lái)指定Response-Request遵循的緩存機(jī)制。各個(gè)指令含義如下

          Cache-Control:Public 可以被任何緩存所緩存()

          Cache-Control:Private 內(nèi)容只緩存到私有緩存中

          Cache-Control:no-cache 所有內(nèi)容都不會(huì)被緩存

          2. HTTP響應(yīng)格式

          在接收和解釋請(qǐng)求消息后,服務(wù)器會(huì)返回一個(gè) HTTP 響應(yīng)消息。與 HTTP 請(qǐng)求類(lèi)似,HTTP 響應(yīng)也是由三個(gè)部分組成,分別是:狀態(tài)行、消息報(bào)頭和響應(yīng)正文。如:

          HTTP/1.1 200 OK

          Date: Sun, 17 Mar 2013 08:12:54 GMT

          Server: Apache/2.2.8 (Win32) PHP/5.2.5

          X-Powered-By: PHP/5.2.5

          Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/

          Expires: Thu, 19 Nov 1981 08:52:00 GMT

          Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

          Pragma: no-cache

          Content-Length: 4393

          Keep-Alive: timeout=5, max=100

          Connection: Keep-Alive

          Content-Type: text/html; charset=utf-8

          <html>

          <head>

          <title>HTTP響應(yīng)示例<title>

          </head>

          <body>

          Hello HTTP!

          </body>

          </html>

          1、狀態(tài)行

          狀態(tài)行由協(xié)議版本、數(shù)字形式的狀態(tài)代碼,及相應(yīng)的狀態(tài)描述組成,各元素之間以空格分隔,結(jié)尾時(shí)回車(chē)換行符,格式如下:

          HTTP-Version Status-Code Reason-Phrase CRLF

          HTTP-Version 表示服務(wù)器 HTTP 協(xié)議的版本,Status-Code 表示服務(wù)器發(fā)回的響應(yīng)代碼,Reason-Phrase 表示狀態(tài)代碼的文本描述,CRLF 表示回車(chē)換行。例如:

          HTTP/1.1 200 OK (CRLF)

          狀態(tài)代碼與狀態(tài)描述

          狀態(tài)代碼由 3 位數(shù)字組成, 表示請(qǐng)求是否被理解或被滿足,狀態(tài)描述給出了關(guān)于狀態(tài)碼的簡(jiǎn)短的文字描述。狀態(tài)碼的第一個(gè)數(shù)字定義了響應(yīng)類(lèi)別,后面兩位數(shù)字沒(méi)有具體分類(lèi)。第一個(gè)數(shù)字有 5 種取值,如下所示。

          • 1xx:指示信息——表示請(qǐng)求已經(jīng)接受,繼續(xù)處理
          • 2xx:成功——表示請(qǐng)求已經(jīng)被成功接收、理解、接受。
          • 3xx:重定向——要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作
          • 4xx:客戶(hù)端錯(cuò)誤——請(qǐng)求有語(yǔ)法錯(cuò)誤或請(qǐng)求無(wú)法實(shí)現(xiàn)
          • 5xx:服務(wù)器端錯(cuò)誤——服務(wù)器未能實(shí)現(xiàn)合法的請(qǐng)求。

          常見(jiàn)狀態(tài)代碼、狀態(tài)描述、說(shuō)明:

          200 OK //客戶(hù)端請(qǐng)求成功

          400 Bad Request //客戶(hù)端請(qǐng)求有語(yǔ)法錯(cuò)誤,不能被服務(wù)器所理解

          401 Unauthorized //請(qǐng)求未經(jīng)授權(quán),這個(gè)狀態(tài)代碼必須和WWW-Authenticate報(bào)頭域一起使用

          403 Forbidden //服務(wù)器收到請(qǐng)求,但是拒絕提供服務(wù)

          404 Not Found //請(qǐng)求資源不存在,eg:輸入了錯(cuò)誤的URL

          500 Internal Server Error //服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤

          503 Server Unavailable //服務(wù)器當(dāng)前不能處理客戶(hù)端的請(qǐng)求,一段時(shí)間后可能恢復(fù)正常

          2、響應(yīng)正文

          響應(yīng)正文就是服務(wù)器返回的資源的內(nèi)容,響應(yīng)頭和正文之間也必須用空行分隔。如:

          1. <html>
          2. <head>
          3. <title>HTTP響應(yīng)示例<title>
          4. </head>
          5. <body>
          6. Hello HTTP!
          7. </body>
          8. </html>

          3 、響應(yīng)頭信息

          HTTP最常見(jiàn)的響應(yīng)頭如下所示:

          Cache頭域

          Date:

          作用:生成消息的具體時(shí)間和日期,即當(dāng)前的GMT時(shí)間。

          例如: Date: Sun, 17 Mar 2013 08:12:54 GMT

          Expires:

          作用: 瀏覽器會(huì)在指定過(guò)期時(shí)間內(nèi)使用本地緩存,指明應(yīng)該在什么時(shí)候認(rèn)為文檔已經(jīng)過(guò)期,從而不再緩存它。

          例如: Expires: Thu, 19 Nov 1981 08:52:00 GMT  

          Vary

          作用:

          例如: Vary: Accept-Encoding

          Cookie/Login 頭域

          P3P

          作用: 用于跨域設(shè)置Cookie, 這樣可以解決iframe跨域訪問(wèn)cookie的問(wèn)題

          例如: P3P: CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR

          Set-Cookie

          作用: 非常重要的header, 用于把cookie 發(fā)送到客戶(hù)端瀏覽器, 每一個(gè)寫(xiě)入cookie都會(huì)生成一個(gè)Set-Cookie.

          例如: Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/

          Entity實(shí)體頭域:

          實(shí)體內(nèi)容的屬性,包括實(shí)體信息類(lèi)型,長(zhǎng)度,壓縮方法,最后一次修改時(shí)間,數(shù)據(jù)有效性等。

          ETag:

          作用: 和If-None-Match 配合使用。 (實(shí)例請(qǐng)看上節(jié)中If-None-Match的實(shí)例)

          例如: ETag: "03f2b33c0bfcc1:0"

          Last-Modified:

          作用: 用于指示資源的最后修改日期和時(shí)間。(實(shí)例請(qǐng)看上節(jié)的If-Modified-Since的實(shí)例)

          例如: Last-Modified: Wed, 21 Dec 2011 09:09:10 GMT

          Content-Type:

          作用:WEB服務(wù)器告訴瀏覽器自己響應(yīng)的對(duì)象的類(lèi)型和字符集,

          例如:

          Content-Type: text/html; charset=utf-8

            Content-Type:text/html;charset=GB2312

            Content-Type: image/jpeg

          Content-Length:

          指明實(shí)體正文的長(zhǎng)度,以字節(jié)方式存儲(chǔ)的十進(jìn)制數(shù)字來(lái)表示。在數(shù)據(jù)下行的過(guò)程中,Content-Length的方式要預(yù)先在服務(wù)器中緩存所有數(shù)據(jù),然后所有數(shù)據(jù)再一股腦兒地發(fā)給客戶(hù)端。

            例如: Content-Length: 19847

          Content-Encoding:

          作用:文檔的編碼(Encode)方法。一般是壓縮方式。

          WEB服務(wù)器表明自己使用了什么壓縮方法(gzip,deflate)壓縮響應(yīng)中的對(duì)象。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載時(shí)間。

          例如:Content-Encoding:gzip

          Content-Language:

          作用: WEB服務(wù)器告訴瀏覽器自己響應(yīng)的對(duì)象的語(yǔ)言者

          例如: Content-Language:da

          Miscellaneous 頭域

          Server:

          作用:指明HTTP服務(wù)器的軟件信息

          例如:Apache/2.2.8 (Win32) PHP/5.2.5

          X-Powered-By:

          作用:表示網(wǎng)站是用什么技術(shù)開(kāi)發(fā)的

          例如: X-Powered-By: PHP/5.2.5

          Transport頭域

          Connection:

          例如: Connection: keep-alive 當(dāng)一個(gè)網(wǎng)頁(yè)打開(kāi)完成后,客戶(hù)端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接不會(huì)關(guān)閉,如果客戶(hù)端再次訪問(wèn)這個(gè)服務(wù)器上的網(wǎng)頁(yè),會(huì)繼續(xù)使用這一條已經(jīng)建立的連接

          例如: Connection: close 代表一個(gè)Request完成后,客戶(hù)端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接會(huì)關(guān)閉, 當(dāng)客戶(hù)端再次發(fā)送Request,需要重新建立TCP連接。

          Location頭域

          Location:

          作用: 用于重定向一個(gè)新的位置, 包含新的URL地址

          實(shí)例請(qǐng)看304狀態(tài)實(shí)例

          HTTP協(xié)議是無(wú)狀態(tài)的和Connection: keep-alive的區(qū)別

            無(wú)狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒(méi)有記憶能力,服務(wù)器不知道客戶(hù)端是什么狀態(tài)。從另一方面講,打開(kāi)一個(gè)服務(wù)器上的網(wǎng)頁(yè)和你之前打開(kāi)這個(gè)服務(wù)器上的網(wǎng)頁(yè)之間沒(méi)有任何聯(lián)系。

            HTTP是一個(gè)無(wú)狀態(tài)的面向連接的協(xié)議,無(wú)狀態(tài)不代表HTTP不能保持TCP連接,更不能代表HTTP使用的是UDP協(xié)議(無(wú)連接)。

            從HTTP/1.1起,默認(rèn)都開(kāi)啟了Keep-Alive,保持連接特性,簡(jiǎn)單地說(shuō),當(dāng)一個(gè)網(wǎng)頁(yè)打開(kāi)完成后,客戶(hù)端和服務(wù)器之間用于傳輸HTTP數(shù)據(jù)的TCP連接不會(huì)關(guān)閉,如果客戶(hù)端再次訪問(wèn)這個(gè)服務(wù)器上的網(wǎng)頁(yè),會(huì)繼續(xù)使用這一條已經(jīng)建立的連接。

            Keep-Alive不會(huì)永久保持連接,它有一個(gè)保持時(shí)間,可以在不同的服務(wù)器軟件(如Apache)中設(shè)定這個(gè)時(shí)間。

          3. 瀏覽器緩存

          瀏覽器緩存:包括頁(yè)面html緩存和圖片js,css等資源的緩存。如下圖,瀏覽器緩存是基于把頁(yè)面信息保存到用戶(hù)本地電腦硬盤(pán)里。

          1、緩存的優(yōu)點(diǎn):

          1)服務(wù)器響應(yīng)更快:因?yàn)檎?qǐng)求從緩存服務(wù)器(離客戶(hù)端更近)而不是源服務(wù)器被相應(yīng),這個(gè)過(guò)程耗時(shí)更少,讓服務(wù)器看上去響應(yīng)更快。

          2)減少網(wǎng)絡(luò)帶寬消耗:當(dāng)副本被重用時(shí)會(huì)減低客戶(hù)端的帶寬消耗;客戶(hù)可以節(jié)省帶寬費(fèi)用,控制帶寬的需求的增長(zhǎng)并更易于管理。

          2、緩存工作原理

          頁(yè)面緩存狀態(tài)是由http header決定的,一個(gè)瀏覽器請(qǐng)求信息,一個(gè)是服務(wù)器響應(yīng)信息。主要包括Pragma: no-cache、Cache-Control、 Expires、 Last-Modified、If-Modified-Since。其中Pragma: no-cache由HTTP/1.0規(guī)定,Cache-Control由HTTP/1.1規(guī)定。

          工作原理圖:

          從圖中我們可以看到原理主要分三步:

          1. 第一次請(qǐng)求:瀏覽器通過(guò)http的header報(bào)頭,附帶Expires,Cache-Control,Last-Modified/Etag向服務(wù)器請(qǐng)求,此時(shí)服務(wù)器記錄第一次請(qǐng)求的Last-Modified/Etag
          2. 再次請(qǐng)求:當(dāng)瀏覽器再次請(qǐng)求的時(shí)候,請(qǐng)求頭附帶Expires,Cache-Control,If-Modified-Since/Etag向服務(wù)器請(qǐng)求
          3. 服務(wù)器根據(jù)第一次記錄的Last-Modified/Etag和再次請(qǐng)求的If-Modified-Since/Etag做對(duì)比,判斷是否需要更新,服務(wù)器通過(guò)這兩個(gè)頭判斷本地資源未發(fā)生變化,客 戶(hù)端不需要重新下載,返回304響應(yīng)。常見(jiàn)流程如下圖所示:

          與緩存相關(guān)的HTTP擴(kuò)展消息頭

          Expires:設(shè)置頁(yè)面過(guò)期時(shí)間,格林威治時(shí)間GMT

          Cache-Control:更細(xì)致的控制緩存的內(nèi)容

          Last-Modified:請(qǐng)求對(duì)象最后一次的修改時(shí)間 用來(lái)判斷緩存是否過(guò)期 通常由文件的時(shí)間信息產(chǎn)生

          ETag:響應(yīng)中資源的校驗(yàn)值,在服務(wù)器上某個(gè)時(shí)段是唯一標(biāo)識(shí)的。ETag是一個(gè)可以 與Web資源關(guān)聯(lián)的記號(hào)(token),和Last-Modified功能才不多,也是一個(gè)標(biāo)識(shí)符,一般和Last-Modified一起使用,加強(qiáng)服務(wù)器判斷的準(zhǔn)確度。

          Date:服務(wù)器的時(shí)間

          If-Modified-Since:客戶(hù)端存取的該資源最后一次修改的時(shí)間,用來(lái)和服務(wù)器端的Last-Modified做比較

          If-None-Match:客戶(hù)端存取的該資源的檢驗(yàn)值,同ETag。

          Cache-Control的主要參數(shù)

          Cache-Control: private/public Public 響應(yīng)會(huì)被緩存,并且在多用戶(hù)間共享。 Private 響應(yīng)只能夠作為私有的緩存,不能再用戶(hù)間共享。

          Cache-Control: no-cache:不進(jìn)行緩存

          Cache-Control: max-age=x:緩存時(shí)間 以秒為單位

          Cache-Control: must-revalidate:如果頁(yè)面是過(guò)期的 則去服務(wù)器進(jìn)行獲取。

          2、關(guān)于圖片,css,js,flash的緩存

          這個(gè)主要通過(guò)服務(wù)器的配置來(lái)實(shí)現(xiàn)這個(gè)技術(shù),如果使用apache服務(wù)器的話,可以使用mod_expires模塊來(lái)實(shí)現(xiàn):

          編譯mod_expires模塊:

          Cd /root/httpd-2.2.3/modules/metadata

          /usr/local/apache/bin/apxs -i -a -c mod_expires.c //編譯

          編輯httpd.conf配置:添加下面內(nèi)容

          <IfModule mod_expires.c>

          ExpiresActive on

          ExpiresDefault "access plus 1 month"

          ExpiresByType text/html "access plus 1 months"

          ExpiresByType text/css "access plus 1 months"

          ExpiresByType image/gif "access plus 1 months"

          ExpiresByType image/jpeg "access plus 1 months"

          ExpiresByType image/jpg "access plus 1 months"

          ExpiresByType image/png "access plus 1 months"

          EXpiresByType application/x-shockwave-flash "access plus 1 months"

          EXpiresByType application/x-javascript "access plus 1 months"

          #ExpiresByType video/x-flv "access plus 1 months"

          </IfModule>

          解釋?zhuān)旱谝痪?-開(kāi)啟服務(wù)

          第二句--默認(rèn)時(shí)間是一個(gè)月

          在下面是關(guān)于各種類(lèi)型的資源的緩存時(shí)間設(shè)置


          主站蜘蛛池模板: 精品亚洲AV无码一区二区三区| 一区二区三区在线免费看| 中文字幕aⅴ人妻一区二区| 国产成人一区二区三区在线| 中文字幕一区二区三匹| 精品久久综合一区二区| 中文字幕在线一区二区在线| 美女福利视频一区二区| 亚洲av乱码中文一区二区三区| 亚洲国产老鸭窝一区二区三区 | 国产vr一区二区在线观看| 日韩最新视频一区二区三| 精品久久一区二区三区| 国产不卡视频一区二区三区| 国产Av一区二区精品久久| 国内精品一区二区三区东京| 精品爆乳一区二区三区无码av| 丰满少妇内射一区| 国产在线视频一区二区三区98| 中文字幕一区二区三| 制服丝袜一区二区三区| 国产亚洲欧洲Aⅴ综合一区| 亚洲性日韩精品国产一区二区| 日韩精品一区二区三区在线观看| 亚洲日韩一区精品射精| 国产精品区一区二区三| 免费一区二区视频| 国产日产久久高清欧美一区| 国产福利日本一区二区三区| 暖暖免费高清日本一区二区三区 | 国精产品一区一区三区| 夜夜嗨AV一区二区三区 | 久久精品无码一区二区日韩AV | 亚洲日韩国产精品第一页一区| 精品无码人妻一区二区三区不卡 | 无码欧精品亚洲日韩一区夜夜嗨| 一区二区三区在线|日本| 亚洲线精品一区二区三区| 色窝窝无码一区二区三区色欲| 国产美女在线一区二区三区| 日本免费一区二区三区最新vr|