WEB 請求處理 一:瀏覽器 請求發起處理

最近,終于要把《WEB請求處理系列》提上日程了,一直答應小伙伴們給分享一套完整的WEB請求處理流程:從瀏覽器、Nginx、Servlet容器,最終到應用程序WEB請求的一個處理流程,前段時間由于其他工作事情的安排,一直未進行整理。不過還好該系列終于啟動了,給大家分享的同時,也順便整理下自己的思路,以便溫故而知新吧。希望大家都能在此過程中得到新的收獲吧。

本系列主要分五部分:

1.《WEB請求處理一:瀏覽器請求發起處理》:分析用戶在瀏覽器中輸入URL地址,瀏覽器如何找到服務器地址的過程,并發起請求;

2.《WEB請求處理二:Nginx請求反向代理》:分析請求在達反向代理服務器內部處理過程;

3.《WEB請求處理三:Servlet容器請求處理》:分析請求在Servlet容器內部處理過程,并找到目標應用程序;

4.《WEB請求處理四:WEB MVC框架請求處理》:分析請求在應用程序內部,開源MVC框架的處理過程;

5.《WEB請求處理五:瀏覽器請求響應處理》:分析請求在服務器端處理完成后,瀏覽器渲染響應頁面過程;

為直觀明了,先上一張圖,紅色部分為本章所述模塊:

本章所述模塊

1 B/S網絡架構概述#

我們先了解下B/S網絡架構是什么?B/S網絡架構從前端到后端都得到了簡化,都基于統一的應用層協議HTTP來交互數據,HTTP協議采用無狀態的短鏈接的通信方式,通常情況下,一次請求就完成了一次數據交互,通常也對應一個業務邏輯,然后這次通信連接就斷開了。采用這種方式是為了能夠同時服務更多的用戶,因為當前互聯網應用每天都會處理上億的用戶請求,不可能每個用戶訪問一次后就一直保持住這個連接

當一個用戶在瀏覽器里輸入www.google.com這個URL時,將會發生如下操作:

  1. 首先,瀏覽器會請求DNS把這個域名解析成對應的IP地址

  2. 然后,根據這個IP地址在互聯網上找到對應的服務器,建立Socket連接,向這個服務器發起一個HTTP Get請求,由這個服務器決定返回默認的數據資源給訪問的用戶;

  3. 在服務器端實際上還有復雜的業務邏輯:服務器可能有多臺,到底指定哪臺服務器處理請求,這需要一個負載均衡設備來平均分配所有用戶的請求;

  4. 還有請求的數據是存儲在分布式緩存里還是一個靜態文件中,或是在數據庫里

  5. 當數據返回瀏覽器時,瀏覽器解析數據發現還有一些靜態資源(如:css,js或者圖片)時又會發起另外的HTTP請求,而這些請求可能會在CDN上,那么CDN服務器又會處理這個用戶的請求;

以上具體流程,如圖所示:

以上具體流程,如圖所示

不管網絡架構如何變化,但是始終有一些固定不變的原則需要遵守:

  1. 互聯網上所有資源都要用一個URL來表示。URL就是統一資源定位符;

  2. 必須基于HTTP協議與服務端交互;

  3. 數據展示必須在瀏覽器中進行;

2 HTTP協議解析#

B/S網絡架構的核心是HTTP協議,最重要的就是要熟悉HTTP協議中的HTTP Header,HTTP Header控制著互聯網上成千上萬的用戶的數據傳輸。最關鍵的是,它控制著用戶瀏覽器的渲染行為和服務器的執行邏輯

常見的HTTP請求頭:

常見的HTTP請求頭

常見的HTTP響應頭:

常見的HTTP響應頭

常見的HTTP狀態碼:

常見的HTTP狀態碼

2.1 瀏覽器緩存機制##

當我們使用Ctrl+F5組合鍵刷新一個頁面時,首先是在瀏覽器端,會直接向目標URL發送請求,而不會使用瀏覽器緩存的數據;其次即使請求發送到服務端,也有可能訪問到的是緩存的數據。所以在HTTP的請求頭中會增加一些請求頭,它告訴服務端我們要獲取最新的數據而非緩存。最重要的是在請求Head中增加了兩個請求項Pragma:no-cache和Cache-Control:no-cache

  1. Cache-Control/Pragma

這個HTTP Head字段用于指定所有緩存機制在整個請求/響應鏈中必須服從的指令,如果知道該頁面是否為緩存,不僅可以控制瀏覽器,還可以控制和HTTP協議相關的緩存或代理服務器

Cache-Control/Pragma字段的可選值:

Cache-Control/Pragma字段的可選值

Cache-Control請求字段被各個瀏覽器支持的較好,而且它的優先級也比較高,它和其他一些請求字段(如Expires)同時出現時,Cache-Control會覆蓋其他字段

Pragma字段的作用和Cache-Control有點類似,它也是在HTTP頭中包含一個特殊的指令,使相關的服務器來遵守,最常用的就是Pragma:no-cache,它和Cache-Control:no-cache的作用是一樣的

  1. Expires 緩存過期時間

Expires通常的使用格式是Expires:Sat,25 Feb 2012 12:22:17 GMT,后面跟著一個日期和時間,超過這個值后,緩存的內容將失效,也就是瀏覽器在發出請求之前檢查這個頁面的這個字段,看該頁面是否已經過期了,過期了將重新向服務器發起請求

  1. Last-Modified/Etag 最后修改時間

Last-Modified字段一般用于表示一個服務器上的字段的最后修改時間,資源可以是靜態(靜態內容自動加上Last-Modified)或者動態的內容(如Servlet提供了一個getLastModified方法用于檢查某個動態內容是否已經更新),通過這個最后修改時間可以判斷當前請求的資源是否是最新的

一般服務器端在響應頭中返回一個Last-Modified字段,告訴瀏覽器這個頁面的最后修改時間,如:Sat,25 Feb 2012 12:55:04 GMT,瀏覽器再次請求時在請求頭中增加一個If-Modified-Since:Sat,25 Feb 2012 12:55:04 GMT字段,詢問當前緩存的頁面是否是最新的,如果是最新的就會返回304狀態碼,告訴瀏覽器是最新的,服務器也不會傳輸新的數據。

與Last-Modified字段有類似功能的還有一個Etag字段,這個字段的作用是讓服務端給每個頁面分配一個唯一編號,然后通過這個編號來區分當前這個頁面是否是最新的。這種方式比使用Last-Modified更加靈活,但是在后端的Web服務器有多臺時比較難處理,因為每個Web服務器都要記住網站的所有資源編號,否則瀏覽器返回這個編號就沒有意義了

3 WEB工作流程#

對于正常的上網過程,系統其實是這樣做的:

瀏覽器本身是一個客戶端,當你輸入URL的時候,首先瀏覽器會去請求DNS服務器,通過DNS獲取相應的域名對應的IP,然后通過IP地址找到IP對應的服務器后,要求建立TCP連接,等瀏覽器發送完HTTP Request(請求)包后,服務器接收到請求包之后才開始處理請求包,服務器調用自身服務,返回HTTP Response(響應)包;客戶端收到來自服務器的響應后開始渲染這個Response包里的主體(body),等收到全部的內容隨后斷開與該服務器之間的TCP連接。

Web請求的工作原理

Web請求的工作原理可以簡單地歸納為:

  1. 瀏覽器通過DNS域名解析到服務器IP

  2. 客戶機通過TCP/IP協議建立到服務器的TCP連接

  3. 客戶端向服務器發送HTTP協議請求包,請求服務器里的資源文檔;

  4. 服務器向客戶機發送HTTP協議應答包,如果請求的資源包含有動態語言的內容,那么服務器會調用動態語言的解釋引擎負責處理“動態內容”,并將處理得到的數據返回給客戶端;

  5. 客戶機與服務器斷開。由客戶端解釋HTML文檔,在客戶端屏幕上渲染圖形結果;

一個簡單的HTTP事務就是這樣實現的,看起來很復雜,原理其實是挺簡單的。需要注意的是客戶機與服務器之間的通信是非持久連接的,也就是當服務器發送了應答后就與客戶機斷開連接,等待下一次請求。

4 DNS域名解析#

4.1 DNS域名解析過程##

當用戶在瀏覽器中輸入域名,如:www.google.com,并按下回車后,DNS解析過程大體如下:

DNS解析過程

  1. 瀏覽器緩存檢查(本機)

瀏覽器會首先搜索瀏覽器自身的DNS緩存(緩存時間比較短,大概只有1分鐘,且只能容納1000條緩存),看自身的緩存中是否有www.google.com對應的條目,而且沒有過期,如果有且沒有過期則解析到此結束

瀏覽器緩存域名也是有限制的,不僅瀏覽器緩存大小有限制,而且緩存的時間也有限制,通常情況下為幾分鐘到幾小時不等,域名被緩存的時間限制可以通過TTL屬性來設置。這個緩存時間太長和太短都不好,如果緩存時間太長,一旦域名被解析到的IP有變化,會導致被客戶端緩存的域名無法解析到變化后的IP地址,以致該域名不能正常解析,這段時間內有可能會有一部分用戶無法訪問網站。如果時間設置太短,會導致用戶每次訪問網站都要重新解析一次域名。

注:我們怎么查看Chrome自身的緩存?可以使用 chrome://net-internals/#dns 來進行查看

查看Chrome自身的DNS緩存

  1. 操作系統緩存檢查(本機)+hosts解析(本機)

如果瀏覽器自身的緩存里面沒有找到對應的條目,其實操作系統也會有一個域名解析的過程,那么Chrome會首先搜索操作系統自身的DNS緩存中是否有這個域名對應的DNS解析結果,如果找到且沒有過期則停止搜索解析到此結束

其次在Linux中可以通過/etc/hosts文件來設置,你可以將任何域名解析到任何能夠訪問的IP地址。如果你在這里指定了一個域名對應的IP地址,那么瀏覽器會首先使用這個IP地址。當解析到這個配置文件中的某個域名時,操作系統會在緩存中緩存這個解析結果,緩存的時間同樣是受這個域名的失效時間和緩存的空間大小控制的。

  1. 本地區域名服務器解析(LDNS)

如果在hosts文件中也沒有找到對應的條目,瀏覽器就會發起一個DNS的系統調用,就會向本地配置的首選DNS服務器(LDNS一般是電信運營商提供的,也可以使用像Google提供的DNS服務器)發起域名解析請求(通過的是UDP協議向DNS的53端口發起請求,這個請求是遞歸的請求,也就是運營商的DNS服務器必須得提供給我們該域名的IP地址)。

在我們的網絡配置中都會有“DNS服務器地址”這一項,這個地址就用于解決前面所說的如果兩個過程無法解析時要怎么辦,操作系統會把這個域名發送給這里設置的LDNS,也就是本地區的域名服務器這個DNS通常都提供給你本地互聯網接入的一個DNS解析服務,例如你是在學校接入互聯網,那么你的DNS服務器肯定在你的學校,如果你是在一個小區接入互聯網的,那這個DNS就是提供給你接入互聯網的應用提供商,即電信或者聯通,也就是通常所說的SPA,那么這個DNS通常也會在你所在城市的某個角落,通常不會很遠。這個專門的域名解析服務器性能都會很好,它們一般都會緩存域名解析結果,當然緩存時間是受域名的失效時間控制的,一般緩存空間不是影響域名失效的主要因素。大約80%的域名解析都到這里就已經完成了,所以LDNS主要承擔了域名的解析工作。

運營商的DNS服務器首先查找自身的緩存,找到對應的條目,且沒有過期,則解析成功。

運營商的DNS服務器

  1. 根域名服務器解析(Root Server)

如果LDNS沒有找到對應的條目,則由運營商的DNS代我們的瀏覽器發起迭代DNS解析請求。它首先是會找根域的DNS的IP地址(這個DNS服務器都內置13臺根域的DNS的IP地址),找到根域的DNS地址,就會向其發起請求(請問www.google.com這個域名的IP地址是多少啊?)。

  1. 根域名服務器返回給本地域名服務器一個所查詢域的主域名服務器(gTLD Server)地址,gTLD是國際頂級域名服務器,如.com、.cn、.org等,全球只有13臺左右。

根域發現這是一個頂級域com域的一個域名,于是就告訴運營商的DNS我不知道這個域名的IP地址,但是我知道com域的IP地址,你去找它去。

  1. 本地域名服務器(Local DNS Server)再向上一步返回的gTLD服務器發送請求

于是運營商的DNS就得到了com域的IP地址,又向com域的IP地址發起了請求(請問www.google.com這個域名的IP地址是多少?),com域這臺服務器告訴運營商的DNS我不知道www.google.com這個域名的IP地址,但是我知道google.com這個域的DNS地址,你去找它去。

  1. 接受請求的gTLD服務器查找并返回此域名對應的Name Server域名服務器的地址,這個Name Server通常就是你注冊的域名服務器,例如你在某個域名服務提供商申請的域名,那么這個域名解析任務就由這個域名提供商的服務器來完成。

于是運營商的DNS又向google.com這個域名的DNS地址(這個一般就是由域名注冊商提供的,像萬網,新網等)發起請求(請問www.google.com這個域名的IP地址是多少?),這個時候google.com域的DNS服務器一查,果真在我這里,于是就把找到的結果發送給運營商的DNS服務器,這個時候運營商的DNS服務器就拿到了www.google.com這個域名對應的IP地址

  1. Name Server域名服務器會查詢存儲的域名和IP的映射關系表,正常情況下都根據域名得到目標IP記錄,連同一個TTL值返回給DNS Server域名服務器。

  2. 返回該域名對應的IP和TTL值,Local DNS Server會緩存這個域名和IP的對應關系,緩存的時間由TTL值控制。

  3. 把解析的結果返回給用戶,用戶根據TTL值緩存在本地系統緩存中,域名解析過程結束

通過上面的步驟,我們最后獲取的是IP地址,也就是瀏覽器最后發起請求的時候是基于IP來和服務器做信息交互的。在實際的DNS解析過程中,可能還不止這10個步驟,如Name Server也可能有多級,或者有一個GTM來負載均衡控制,這都有可能會影響域名解析的過程。根據以上解析流程,DNS解析整個過程,分為:遞歸查詢過程和迭代查詢過程。如圖所示:

DNS解析整個過程

所謂 遞歸查詢過程 就是 “查詢的遞交者” 更替, 而 迭代查詢過程 則是 “查詢的遞交者”不變。

舉個例子來說,你想知道某個一起上法律課的女孩的電話,并且你偷偷拍了她的照片,回到寢室告訴一個很仗義的哥們兒,這個哥們兒二話沒說,拍著胸脯告訴你,甭急,我替你查(此處完成了一次遞歸查詢,即,問詢者的角色更替)。然后他拿著照片問了學院大四學長,學長告訴他,這姑娘是xx系的;然后這哥們兒馬不停蹄又問了xx系的辦公室主任助理同學,助理同學說是xx系yy班的,然后很仗義的哥們兒去xx系yy班的班長那里取到了該女孩兒電話。(此處完成若干次迭代查詢,即,問詢者角色不變,但反復更替問詢對象)最后,他把號碼交到了你手里。完成整個查詢過程。

4.2 跟蹤域名解析過程##

在Linux系統中還可以使用dig命名來查詢DNS的解析過程,如下所示:dig +cmd +trace www.google.com

使用dig命名來查詢DNS的解析過程

上面清楚地顯示了整個域名是如何發起和解析的,從根域名(.)到gTLD Server(.com.)再到Name Server (google.com.)的整個過程都顯示出來了。還可以看出DNS的服務器有多個備份,可以從任何一臺查詢到解析結果。

4.3 清除緩存的域名##

我們知道DNS域名解析后會緩存解析結果,其中主要在兩個地方緩存結果,一個是Local DNS Server,另外一個是用戶的本地機器。這兩個緩存都是TTL值和本機緩存大小控制的,但是最大緩存時間是TTL值,基本上Local DNS Server的緩存時間就是TTL控制的,很難人工介入,但是我們的本機緩存可以通過如下方式清除。

在Linux下可以通過/etc/init.d/nscd restart來清除DNS緩存。如下:

在Linux下清除DNS緩存

JVM緩存DNS解析結果:

在Java應用中JVM也會緩存DNS的解析結果,這個緩存是在InetAddress類中完成的,而且這個緩存時間還比較特殊,它有兩種緩存策略:一種是正確解析結果緩存,另一種是失敗的解析結果緩存。這兩個緩存時間由兩個配置項控制,配置項是在%JAVA_ HOME%\lib\security\java.security文件中配置的。兩個配置項分別是networkaddress.cache.ttl 和networkaddress.cache.negative.ttl,它們的默認值分別是-1(永不失效)和10(緩存10秒)

要修改這兩個值同樣有幾種方式,分別是:直接修改java.security文件中的默認值、在Java的啟動參數中增加-Dsun.net.inetaddr.ttl=xxx來修改默認值、通過InetAddress類動態修改。

在這里還要特別強調一下,如果我們需要用InetAddress類解析域名時,一定要是單例模式,不然會有嚴重的性能問題,如果每次都創建InetAddress實例,每次都要進行一次完整的域名解析,非常耗時,這點要特別注意。

4.4 幾種域名解析方式##

  1. A記錄,A代表的是Address,用來指定域名對應的IP地址

如將item.taobao.com指定到115.238.23.241,將switch.taobao.com指定到121.14.24.241。A記錄可以將多個域名解析到一個IP地址,但是不能將一個域名解析到多個IP地址

  1. MX記錄,表示的是Mail Exchange,就是可以將某個域名下的郵件服務器指向自己的Mail Server

如taobao.com域名的A記錄IP地址是115.238.25.245,如果MX記錄設置為115.238.25.246,是xxx@taobao.com的郵件路由,DNS會將郵件發送到115.238.25.246所在的服務器,而正常通過Web請求的話仍然解析到A記錄的IP地址

  1. CNAME記錄,全稱是Canonical Name(別名解析),所謂的別名解析就是可以為一個域名設置一個或者多個別名

如將taobao.com解析到xulingbo.net,將srcfan.com也解析到xulingbo.net,其中xulingbo.net分別是taobao.com和srcfan.com的別名。前面的跟蹤域名解析中的“www.taobao.com. 1542 IN CNAME www.gslb.taobao.com”就是CNAME解析。

  1. NS記錄,為某個域名指定DNS解析服務器,也就是這個域名有指定的IP地址的DNS服務器去解析

前面的“google.com. 172800 IN NS ns4.google.com.”就是NS解析。

  1. TXT記錄,為某個主機名或域名設置說明

如可以為google.com設置TXT記錄為“谷歌|中國”這樣的說明。

4.5 網絡抓包分析##

Linux虛擬機測試,使用命令 wget www.linux178.com 來請求,發現直接使用chrome瀏覽器請求時,干擾請求比較多,所以就使用wget命令來請求,不過使用wget命令只能把index.html請求回來,并不會對index.html中包含的靜態資源(js、css等文件)進行請求

抓包截圖如下:

抓包截圖

1號包,這個是那臺虛擬機在廣播,要獲取192.168.100.254(也就是網關)的MAC地址,因為局域網的通信靠的是MAC地址,它為什么需要跟網關進行通信是因為我們的DNS服務器IP是外圍IP,要出去必須要依靠網關幫我們出去才行

2號包,這個是網關收到了虛擬機的廣播之后,回應給虛擬機的回應,告訴虛擬機自己的MAC地址,于是客戶端找到了路由出口。

3號包,這個包是wget命令向系統配置的DNS服務器提出域名解析請求(準確的說應該是wget發起了一個DNS解析的系統調用),請求的域名www.linux178.com,期望得到的是IP6的地址(AAAA代表的是IPv6地址)

4號包,這個DNS服務器給系統的響應,很顯然目前使用IPv6的還是極少數,所以得不到AAAA記錄的。

5&6號包,這個還是請求解析IPv6地址,但是www.linux178.com.leo.com這個主機名是不存在的,所以得到結果就是no such name。

7號包,這個才是請求的域名對應的IPv4地址(A記錄)。

8號包,DNS服務器不管是從緩存里面,還是進行迭代查詢最終得到了域名的IP地址,響應給了系統,系統再給了wget命令,wget于是得到了www.linux178.com的IP地址,這里也可以看出客戶端和本地的DNS服務器是遞歸的查詢(也就是服務器必須給客戶端一個結果)這就可以開始下一步了,進行TCP的三次握手。

5 發起TCP的3次握手#

拿到域名對應的IP地址之后,User-Agent(一般是指瀏覽器)會以一個隨機端口(1024 < 端口 < 65535)向服務器的WEB程序(常用的有httpd,nginx等)80端口發起TCP的連接請求。這個連接請求(原始的http請求經過TCP/IP4層模型的層層封包)到達服務器端后(這中間通過各種路由設備,局域網內除外),進入到網卡,然后是進入到內核的TCP/IP協議棧(用于識別該連接請求,解封包,一層一層的剝開),還有可能要經過Netfilter防火墻(屬于內核的模塊)的過濾,最終到達WEB程序,最終建立了TCP/IP的連接。

如下圖所示:

03174517_saG0.png

  1. Client首先發送一個連接試探,ACK=0 表示確認號無效,SYN = 1 表示這是一個連接請求或連接接受報文,同時表示這個數據報不能攜帶數據,seq = x 表示Client自己的初始序號(seq = 0 就代表這是第0號包),這時候Client進入syn_sent狀態,表示客戶端等待服務器的回復。

  2. Server監聽到連接請求報文后,如同意建立連接,則向Client發送確認。TCP報文首部中的SYN 和 ACK都置1 ,ack = x + 1表示期望收到對方下一個報文段的第一個數據字節序號是x+1,同時表明x為止的所有數據都已正確收到(ack=1其實是ack=0+1,也就是期望客戶端的第1個包),seq = y 表示Server自己的初始序號(seq=0就代表這是服務器這邊發出的第0號包)。這時服務器進入syn_rcvd,表示服務器已經收到Client的連接請求,等待client的確認。

  3. Client收到確認后還需再次發送確認,同時攜帶要發送給Server的數據。ACK 置1 表示確認號ack= y + 1 有效(代表期望收到服務器的第1個包),Client自己的序號seq= x + 1(表示這就是我的第1個包,相對于第0個包來說的),一旦收到Client的確認之后,這個TCP連接就進入Established狀態,就可以發起http請求了。

看抓包截圖:

抓包截圖

TCP 為什么需要3次握手?

舉個例子:假設一個老外在故宮里面迷路了,看到了小明,于是就有下面的對話:

老外: Excuse me,Can you Speak English?

小明: yes 。

老外: OK,I want ...

在問路之前,老外先問小明是否會說英語,小明回答是的,這時老外才開始問路。

2個計算機通信是靠協議(目前流行的TCP/IP協議)來實現,如果2個計算機使用的協議不一樣,那是不能進行通信的,所以這個3次握手就相當于試探一下對方是否遵循TCP/IP協議,協商完成后就可以進行通信了,當然這樣理解不是那么準確。

為什么HTTP協議要基于TCP來實現?

目前在Internet中所有的傳輸都是通過TCP/IP進行的,HTTP協議作為TCP/IP模型中應用層的協議也不例外,TCP是一個端到端的可靠的面向連接的協議,所以HTTP基于傳輸層TCP協議不用擔心數據的傳輸的各種問題。

6 建立TCP連接后發起http請求#

經過TCP3次握手之后,瀏覽器發起了http的請求(看第?包),使用的http的方法 GET 方法,請求的URL是 / ,協議是HTTP/1.0:

03175340_4j8z.png

下面是第12號包的詳細內容:

03175429_kHoP.png

以上的報文是HTTP請求報文。那么HTTP請求報文和響應報文會是什么格式呢?

起始行:如 GET / HTTP/1.0 (請求的方法 請求的URL 請求所使用的協議)

頭部信息:User-Agent Host等成對出現的值

主體

不管是請求報文還是響應報文都會遵循以上的格式。那么起始行中的請求方法有哪些種呢?

GET: 完整請求一個資源 (常用)

HEAD: 僅請求響應首部

POST: 提交表單 (常用)

PUT: 上傳

DELETE: 刪除

OPTIONS: 返回請求的資源所支持的方法的方法

TRACE: 追求一個資源請求中間所經過的代理

那什么是URL、URI、URN?

URI Uniform Resource Identifier 統一資源標識符,如:scheme://[username:password@]HOST:port/path/to/source

URL Uniform Resource Locator 統一資源定位符,如:http://www.magedu.com/downloads/nginx-1.5.tar.gz

URN Uniform Resource Name 統一資源名稱

URL和URN都屬于URI,為了方便就把URL和URI暫時都通指一個東西。

請求的協議有哪些種?有以下幾種:

http/0.9: stateless

http/1.0: MIME, keep-alive (保持連接), 緩存

http/1.1: 更多的請求方法,更精細的緩存控制,持久連接(persistent connection) 比較常用

下面是Chrome發起的http請求報文頭部信息:

03181252_cIE1.png

Accept 就是告訴服務器端,接受那些MIME類型

Accept-Encoding 這個看起來是接受那些壓縮方式的文件

Accept-Lanague 告訴服務器能夠發送哪些語言

Connection 告訴服務器支持keep-alive特性,TCP連接在發送后將仍然保持打開狀態,于是,瀏覽器可以繼續通過相同的TCP連接發送請求。保持連接節省了為每個請求建立新連接所需的時間,還節約了網絡帶寬。

Cookie 每次請求時都會攜帶上Cookie以方便服務器端識別是否是同一個客戶端

Host 用來標識請求服務器上的那個虛擬主機,比如Nginx里面可以定義很多個虛擬主機,那這里就是用來標識要訪問那個虛擬主機。

User-Agent 用戶代理,一般情況是瀏覽器,也有其他類型,如:wget curl 搜索引擎的蜘蛛等

條件請求頭部:If-Modified-Since是瀏覽器向服務器端詢問某個資源文件如果自從什么時間修改過,那么重新發給我,這樣就保證服務器端資源文件更新時,瀏覽器再次去請求,而不是使用緩存中的文件。

安全請求頭部:Authorization: 客戶端提供給服務器的認證信息;

什么是MIME?

MIME(Multipurpose Internet Mail Extesions 多用途互聯網郵件擴展)是一個互聯網標準,它擴展了電子郵件標準,使其能夠支持非ASCII字符、二進制格式附件等多種格式的郵件消息,這個標準被定義在RFC 2045、RFC 2046、RFC 2047、RFC 2048、RFC 2049等RFC中。 由RFC 822轉變而來的RFC 2822,規定電子郵件標準并不允許在郵件消息中使用7位ASCII字符集以外的字符。正因如此,一些非英語字符消息和二進制文件,圖像,聲音等非文字消息都不能在電子郵件中傳輸。

MIME規定了用于表示各種各樣的數據類型的符號化方法。此外,在萬維網中使用的HTTP協議中也使用了MIME的框架,標準被擴展為互聯網媒體類型。

MIME 遵循以下格式:major/minor 主類型/次類型 例如:

image/jpg

image/gif

text/html

video/quicktime

appliation/x-httpd-php



轉自:https://www.jianshu.com/p/558455228c43
?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448199.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448199.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448199.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

離合器半聯動探秘

離合器踏板作用是切斷發動機和變速箱之間的動力&#xff0c;有利于起步、變速、和停車。那么如何更好的使用它呢&#xff1f; 離合器的五種狀態示意圖 離合器半聯動的使用方法揭密如下&#xff1a; 離合器半聯動的使用探密之一 將離合器抬到車開始動時你就別再抬了&#xff0c;…

Biztalk Server 2006安裝配置

前段時間收到了來自beta.microsoft.com的BTS20006 Beta2的下載地址&#xff0c;這兩天對它進行了一番安裝配置。下面把一些經過和步驟和大家分享一下&#xff0c;手中有一些去年的Biztalk Server2004版本的培訓資料&#xff0c;里面有11個Lab。需要的朋友請留下mail&#xff0c…

apache 官方 Dubbo 文檔

只是分享、記錄一下 dubbo 的文檔地址&#xff1a;apache 官方 Dubbo 文檔 其頁面內容如下&#xff1a;&#xff08;我是用 chrome 直接右鍵翻譯的&#xff0c;原文檔是英文的&#xff09;

制動踏板是什么?

制動踏板就是腳剎&#xff08;行車制動器&#xff09;的踏板&#xff0c;使運行中的機車、車輛及其他運輸工具或機械等停止或減低速度的動作。制動的一般原理是在機器的高速軸上固定一個輪或盤&#xff0c;在機座上安裝與之相適應的閘瓦、帶或盤&#xff0c;在外力作用下使之產…

CSS Framework 960 Grid System (收)

CSS框架 &#xff1a;960 Grid System 官網&#xff1a;http://960.gs/ 什么是框架&#xff1f;框架是一種你能夠使用在你的web項目中概念上的結構。CSS框架一般是CSS文件的集合&#xff0c;包括基本風格的字體排版&#xff0c;表單樣式&#xff0c;表格布局等等&#xff0c;比…

使用線程本地存儲

線程本地存儲&#xff08;TLS&#xff09;使同一進程的多個線程能夠使用由TlsAlloc函數分配的索引來存儲和檢索線程本地的值。在此示例中&#xff0c;在進程啟動時分配索引。當每個線程啟動時&#xff0c;它會分配一個動態內存塊&#xff0c;并使用TlsSetValue函數在TLS槽中存儲…

發動機的工作原理,你知道嗎?

http://auto.jxedt.com/info/5352.htm 發動機是汽車的動力裝置&#xff0c;性能優劣直接影響到汽車性能&#xff0c;發動機的類型很多&#xff0c;結構各異&#xff0c;以適應不同車型的需要。按發動機使用燃料劃分&#xff0c;可分成汽油發動機和柴油發動機等類別。按發動機汽…

官方文檔: Dubbo 框架設計、模塊說明、依賴關系

以下內容全文轉自 apache 官方 dubbo文檔&#xff1a;http://dubbo.apache.org/en-us/docs/dev/design.html 框架設計 圖片描述&#xff1a; 淺藍色背景的左側區域顯示服務用戶界面&#xff0c;淺綠色背景的右側區域顯示服務提供者界面&#xff0c;中心區域顯示兩個側面界面。…

那些花兒

今天上海下雨了&#xff0c;心緒也變得低落&#xff0c;突然很想念宿舍的姐妹。畢業后就自作聰明地和她們失去了聯系&#xff0c;今天去QQ群遛了一圈。虹結婚了&#xff0c;敏還是活得那么瀟灑&#xff0c;笑也在努力地生活... 人生啊&#xff01;總是在向前走&#xff0c;遇…

CreateRemoteThread函數

CreateRemoteThread函數 創建在另一個進程的虛擬地址空間中運行的線程。 使用CreateRemoteThreadEx函數創建在另一個進程的虛擬地址空間中運行的線程&#xff0c;并可選擇指定擴展屬性。 語法 HANDLE CreateRemoteThread(HANDLE hProcess,LPSECURITY_ATTRI…

防火墻問題 Linux系統 /etc/sysconfig/路徑下無iptables文件

虛擬機新裝了一個CentOs7&#xff0c;然后做防火墻配置的時候找不到iptables文件&#xff0c;解決方法如下&#xff1a; 因為默認使用的是firewall作為防火墻&#xff0c;把他停掉裝個iptable systemctl stop firewalld systemctl mask firewalld yum install -y iptables yum …

如果風 知道 ... 如果云 知道 ...

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 //《心靈之音》----- Bandari 來自酷狗。 一直很喜歡聽歌&#xff1a; 喜歡默默的聽、一個人安安靜靜的聽、長長久久的聽、聽得忘乎所…

切記!這樣洗頭最傷身

各種的忙碌已經成為了現代人生活中的一個標志&#xff0c;每天的加班&#xff0c;玩樂到深夜&#xff0c;游戲等&#xff0c;都讓不少的人的洗澡時間都只能在臨睡前&#xff0c;而女人洗頭也只能在晚上臨睡之前洗。如果可以有足夠的時間&#xff0c;等待頭發完全干透了之后&…

可以供MFC調用的,QT實現的DLL(qtwinmigrate實現)

MFC和QT的消息循環機制不同&#xff0c;所以&#xff0c;要讓QT寫的DLL可以供MFC調用&#xff0c;要做一點特殊的處理 #include <qmfcapp.h> #include <qwinwidget.h> #include <QtGui>#include <QtGui/QMessageBox> #include <windows.h> #incl…

離合器的操作技巧

學車其實不難&#xff0c;學車最基本的幾個操作&#xff0c;打方向盤、踩離合、踩剎車、換檔位都是學員需要必學的基本操作&#xff0c;在網絡駕校上有學員反應&#xff0c;對離合器的操作比較難&#xff0c;經常錯誤操作造成熄火等現象&#xff0c;現在瀘州駕校論壇小編整理了…

Linux 上 安裝 nginx、 阿里云服務器上安裝 nginx

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Docker 方式安裝見另一文&#xff1a;Docker 方式安裝 Nginx 、阿里云服務器上裝 Ngnix 1. gcc 安裝 安裝 nginx 需要先將官網下載的源…

CSDN-markdown編輯器使用說明

歡迎使用Markdown編輯器 你好&#xff01; 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章&#xff0c;了解一下Markdown的基本語法知識。 新的改變 我們對Markdown編輯器進行了一些功能拓展與語法支持&#x…

本地Android源代碼庫下載源碼

1. 安裝repo 新建放置repo的bin目錄 $ mkdir ~/bin $ echo "export PATH~/bin:\$PATH" >> ~/.bashrc$ source ~/.bashrc 獲取repo并賦予可執行權限&#xff08;或者參考google官方網站&#xff09; $ curl https://storage.googleapis.com/git-repo-downloads/…

解決: Spring Boot報錯 This application has no explicit mapping ... a fallback

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 啟動spring boot然后訪問頁面的時候&#xff0c;出現如下錯誤&#xff1a; Whitelabel Error PageThis application has no explicit m…

三種錢非常奧妙 花越多就賺越多

世界上有三種錢非常奧妙&#xff0c;你花得越多就賺得越多。這是學校老師不會教的事&#xff0c;讓我們看看&#xff1a; 第一種錢&#xff1a;投資自己&#xff0c;自我成長&#xff0c;學習的錢一定要花&#xff01; 如果我們把世界首富比爾.蓋茨從美國抓到非洲&#xff0c…