[TOC]
1.Web及網(wǎng)絡(luò)基礎(chǔ)
1.1TCP/IP分層
TCP/TP協(xié)議族里重要的一點就是分層。TCP/IP協(xié)議族按層次分為一下4層:應(yīng)用層边器、傳輸層、網(wǎng)絡(luò)層和數(shù)據(jù)鏈路層筛严。
- 應(yīng)用層:應(yīng)用層決定了向用戶提供應(yīng)用服務(wù)時通信的活動醉旦。
TCP/IP協(xié)議族內(nèi)預(yù)存了各類通用的應(yīng)用服務(wù)。比如桨啃,F(xiàn)TP和DNS服務(wù)就是其中兩類车胡,HTTP協(xié)議也處于該層
- 傳輸層: 傳輸層對上層應(yīng)用層,提供處于網(wǎng)絡(luò)連接中的兩臺計算機之間的數(shù)據(jù)傳輸照瘾。(有兩個性質(zhì)不同的協(xié)議:TCP和UDP)
- 網(wǎng)絡(luò)層: 用來處理在網(wǎng)絡(luò)上流動的數(shù)據(jù)包匈棘。數(shù)據(jù)包時網(wǎng)絡(luò)傳輸?shù)淖钚挝弧T搶右?guī)定了通過怎么樣的路徑到達對方計算機析命,把數(shù)據(jù)傳輸給對方主卫。
- 鏈路層(數(shù)據(jù)鏈路層): 用來處理連接網(wǎng)絡(luò)的硬件部分辉浦,包括控制操作系統(tǒng)旨剥、硬件的設(shè)備驅(qū)動,網(wǎng)卡及光纖等物理課件部分嘱朽。硬件上的范疇均在鏈路層的作用范圍之內(nèi)软吐。
1.2TCP/TP通信傳輸流
利用TCP/IP協(xié)議族進行網(wǎng)絡(luò)通信時瘩将,會通過分層順序與對方進行通信。發(fā)送端從應(yīng)用層往下走凹耙,接收端則向應(yīng)用層往上走姿现。
以HTTP舉例說明:
- 首先作為發(fā)送端的客戶端在應(yīng)用層發(fā)出一個想看某個web頁面的HTTP請求
- 為了傳輸方便,傳輸層會將發(fā)送的數(shù)據(jù)(HTTP請求報文)分割肖抱,并在各個報文打上序號標記和端口號轉(zhuǎn)發(fā)給網(wǎng)絡(luò)層备典。
- 網(wǎng)絡(luò)層增加作為通信目的地的MAC地址后轉(zhuǎn)發(fā)給鏈路層
- 服務(wù)端的鏈路層收到數(shù)據(jù)后,按需往應(yīng)用層發(fā)送虐沥。當傳輸?shù)綉?yīng)用層才算真正的收到客戶端發(fā)來的HTTP請求熊经。
- 發(fā)送端在層與層之間傳輸數(shù)據(jù)時,經(jīng)過每一層都會加上一個該層所屬的信息首部欲险。反之接受端在層與層傳輸數(shù)據(jù)時镐依,每經(jīng)過一層時都會把對應(yīng)的首部消去(這種把數(shù)據(jù)信息包裝起來的做法稱之為封裝)。
1.3 與HTTP關(guān)系密切的協(xié)議: IP天试、TCP和DNS
1.3.1 負責傳輸?shù)腎P協(xié)議
IP協(xié)議(這里的IP協(xié)議并不是指IP地址槐壳,位于網(wǎng)絡(luò)層)的作用是把數(shù)據(jù)包傳送給對方,而要保證確實送到對方那里喜每,則需要知道目標的IP地址和MAC地址(MAC地址指的是網(wǎng)卡地址务唐,IP地址可變雳攘,但是MAC地址是不變的。根據(jù)APR協(xié)議就能通過IP地址定位到對應(yīng)的MAC地址)枫笛。
在網(wǎng)絡(luò)上吨灭,通信雙方都在同一個局域網(wǎng)(LAN)的情況是很少的。一般都需要經(jīng)過多臺計算機和網(wǎng)絡(luò)設(shè)備中轉(zhuǎn)才能連接到對方刑巧。這中間的計算機和路由器只能獲取粗略的傳輸路線喧兄,沒有人能全面掌握互聯(lián)網(wǎng)中的傳輸狀況。這種機制稱為路由(routing)啊楚。就像快遞一樣吠冤,物品時通過一個個中轉(zhuǎn)站,最后才能到達目的地恭理。
1.3.2 確闭蓿可靠的TCP協(xié)議
TCP協(xié)議處于傳輸層,提供可靠的字節(jié)流服務(wù)
- 字節(jié)流服務(wù):為了方便傳輸颜价,將大塊數(shù)據(jù)分割成以報文段(segment)為單位的數(shù)據(jù)包
- 可靠:利用三次握手策略(three-way handshaking)確保數(shù)據(jù)能到達目標
三次握手
TCP不會對傳送后的情況置之不理涯保,他一定會向?qū)Ψ酱_認是否成功到達。握手過程中使用了TCP的標志--- SYN(synchronize)和ACK(acknowleagement)拍嵌。
- 發(fā)送端首先發(fā)送一個帶SYN標志的數(shù)據(jù)包給對方遭赂。
- 接收端收到后,回傳一個SYN/ACK標志的數(shù)據(jù)包以示傳達確認信息横辆。
- 最后撇他,發(fā)送端再回傳一個ACK標志的數(shù)據(jù)包,代表握手結(jié)束狈蚤。
-
若在握手過程中某個階段莫名中斷困肩,TCP協(xié)議會再次以相同的順序發(fā)送相同的數(shù)據(jù)包。
三次握手示意圖
1.3.3 負責域名解析的DNS服務(wù)
DNS服務(wù)是和HTTP協(xié)議一樣位于應(yīng)用層的協(xié)議脆侮。它提供域名到IP地址之間的解析服務(wù)锌畸。他提供域名到IP地址之間的解析服務(wù)【副埽或者逆向從IP地址反查域名
2. 簡單的HTTP協(xié)議
2.1. HTTP協(xié)議用于客戶端和服務(wù)端之間的通信
在應(yīng)用HTTP協(xié)議時潭枣,在一條通信線路上,必有一端是客戶端一端是服務(wù)端幻捏。請求訪問資源的一端是客戶端盆犁,而提供資源響應(yīng)的一端是服務(wù)端。兩臺計算機客戶端和服務(wù)端的角色可能互換篡九,但是就一條通信線路來說是固定的谐岁。(服務(wù)器之間互相調(diào)用,發(fā)起請求的一段是客戶端)
2.2. 通過請求和響應(yīng)的交換達成通信
客戶端發(fā)出請求,服務(wù)端回復(fù)響應(yīng)伊佃。
請求報文:一般包括幾個內(nèi)容:請求方法窜司,請求URI, 協(xié)議版本,可選的請求首部字段(請求頭 Request Header)和內(nèi)容實際構(gòu)成
響應(yīng)報文:一般包括: 協(xié)議版本航揉,狀態(tài)碼塞祈,狀態(tài)碼的原因短語,響應(yīng)首部字段(響應(yīng)頭 Response Header)和實體主體構(gòu)成
2.3. HTTP是不保存狀態(tài)的協(xié)議(無狀態(tài)協(xié)議)
HTTP每次新的請求都會對應(yīng)新的響應(yīng)帅涂。協(xié)議本身不會保留之前的一切的請求或者響應(yīng)報文织咧。這么設(shè)計是為了處理大量事務(wù),確保協(xié)議的可伸縮性漠秋。
但是在我實際開發(fā)中,常常需要記住用戶的身份登錄狀態(tài)等等抵屿。
所以HTTP1.1為了實現(xiàn)期望的保持狀態(tài)功能庆锦,于是引入Cookie技術(shù)。當然有現(xiàn)在的token方案(需要客戶端配合轧葛,服務(wù)端在登錄之后返回一個加密的帶有用戶信息的token字符串搂抒,客戶端收到緩存在本地,在以后所有的請求中攜帶上這個token尿扯,服務(wù)端相應(yīng)的就可以解密這個token來判斷用戶的身份)
2.4. 確定資源的URI
第2點談到了請求報文中包括URI求晶,這樣就能定位服務(wù)端的指定資源。 指定請求URI的方式有很多衷笋。
2.5. 告知服務(wù)器意圖的HTTTP方法
HTTP 請求報文中指定了客戶端請求的方法芳杏,常見的方法有GET、POST辟宗、PUT爵赵、DELETE等,每個方法的意圖其實都是有所去別的泊脐。下面是方法說明與支持版本的表格空幻。
2.6. 持久連接節(jié)省通信量
HTTP協(xié)議的初始版本中,每進行一次HTTP通信都要斷開一次TCP連接容客。
隨著計算機的發(fā)展請求的內(nèi)容以及數(shù)量大大增加(隨便一個頁面都有很多的圖片以及其它資源請求)秕铛,因此,每次請求都會造成無謂的TCP連接建立與斷開缩挑,增加通信量的開銷但两。
為了解決這個問題提出了持久連接
持久連接
為了解決上面的問題,HTTP/1.1和一部分的1.0想出了持久連接(HTTP keep-alive)方法调煎。只要任意一端沒有提出斷開連接镜遣,則保持TCP連接狀態(tài)。這樣就可以避免重復(fù)建立連接和斷開連接帶來的額外開銷,Web頁面的顯示速度就提高了
HTTP/1.1默認所有的連接都是持久連接
管線化
持久化連接使得多數(shù)請求以管線化(pipelining)方式發(fā)送成為可能悲关。以前發(fā)送請求后需要等待響應(yīng)才能發(fā)送一個請求谎僻。
并發(fā)請求,一個請求發(fā)出后無需等待響應(yīng)就可以直接發(fā)送下一個請求寓辱。
2.7. 使用Cookie的狀態(tài)管理
前面說了HTTP是無狀態(tài)協(xié)議艘绍,這么設(shè)計不保存狀態(tài)減輕了服務(wù)器的CPU及內(nèi)存資源的消耗。如果需要狀態(tài)就需要在每次的請求報文中附加參數(shù)來管理狀態(tài)秫筏。前面提到了HTTP/1.1引入了Cookie技術(shù)诱鞠。
Cookie技術(shù)通過在請求和響應(yīng)報文中寫入Cookie信息來控制客戶端的狀態(tài)。Cookie會根據(jù)服務(wù)端發(fā)送的響應(yīng)報文內(nèi)的一個叫做Set-Cookie的首部字段信息这敬,通知客戶端保存Cookie航夺。當下次客戶端發(fā)送請求時,請求報文中自動加入Cookie發(fā)送出去崔涂。
3.HTTP報文內(nèi)的HTTP信息
3.1 HTTP報文
HTTP協(xié)議交互的信息HTTP報文阳掐,客戶端解和服務(wù)端的報文分別叫請求報文和響應(yīng)報文。
HTTP報文本身是由多行數(shù)據(jù)(用CR+LF作換行符)構(gòu)成的字符串文本
3.2 請求報文及響應(yīng)報文的結(jié)構(gòu)
- 請求行: 包含用于請求的方法冷蚂,請求URI和HTTP版本
- 狀態(tài)行: 包含表明響應(yīng)結(jié)果的狀態(tài)碼缭保,原因短語和HTTP版本
- 首部字段: 包含請求和相應(yīng)的各種條件和屬性的各類首部。一般有4種首部:通用首部蝙茶, 請求首部艺骂、響應(yīng)首部和實體首部
- 其它: 可能包含HTTP的RFC(草案)里未定義的首部(Cookie等)
3.3 編碼提升傳輸速率
HTTP在傳輸數(shù)據(jù)時可以按照數(shù)據(jù)原貌直接傳輸,也可以在傳輸過程中通過編碼提升傳輸效率隆夯。
- 壓縮傳輸?shù)膬?nèi)容編碼:指明實體內(nèi)容的編碼格式钳恕,客戶端接收后按編碼格式解碼,常用的內(nèi)容編碼有
- gzip(GNU zip)
- compress(Unix系統(tǒng)的標準壓縮)
- deflate(zlib)
- identity (不進行編碼)
- 分割發(fā)送的分塊傳輸編碼: HTTP通信過程中蹄衷,請求的資源時體尚未全部傳輸完成之前苞尝,瀏覽器無法顯示請求頁面,通過把數(shù)據(jù)分割成對快宦芦,能夠讓瀏覽器逐步顯示頁面宙址。
分塊傳輸編碼會將主體分成多個部分(塊)。每一塊都會用16進制來標記塊的大小调卑,而主體的最后一塊會使用‘0(CR+LF)’來標記
3.4 發(fā)送多種數(shù)據(jù)的多部份對象集合(multipart/xx)
發(fā)送郵件時可以發(fā)送多種不同類型的文件抡砂。是因為MIME擴展中使用一種稱為多部份對象集合(multipart)的方法。HTTP中也采納了這種方法(一般像表單提交時恬涧,就是常常包含了字段以及文件)注益。
多部份對象集合包含的對象如下:
-
multipart/form-data:: 在WEB表單文件上傳時使用
imultipart/form-data -
multipart/byteranges:: 狀態(tài)碼206(Partial Content, 部分內(nèi)容)溯捆,響應(yīng)報文包含了多個范圍的內(nèi)容時使用丑搔。請求部分范圍的數(shù)據(jù)。
multipart/byteranges
使用boundary字符串來劃分多部分對象集合指明的各類實體。每個實體的起始行插入'--'+boundary
的標記啤月,而在多部份對象集合結(jié)束的尾部地方插入'--'+boundray+'--'
的標記標志結(jié)束煮仇。
3.5 獲取部分內(nèi)容的范圍請求
起初,當網(wǎng)速不好時谎仲,在下載一個大的文件過程中出現(xiàn)網(wǎng)絡(luò)中斷的情況就必須重新開始浙垫。為了解決這個問題,就需要一種可以恢復(fù)下載的機制郑诺,也就是從中斷處恢復(fù)下載夹姥。
實現(xiàn)該功能就需要指定下載的實體范圍。像這樣指定范圍發(fā)送的請求就叫做范圍請求辙诞。
使用首部字段Range指定資源的byte范圍辙售。 返回的狀態(tài)碼為206.部分內(nèi)容。如果服務(wù)端無法響應(yīng)方位請求飞涂,則會返回狀態(tài)碼為200的完整實體內(nèi)容
3.6 內(nèi)容協(xié)商返回最合適的內(nèi)容
有時候訪問同一個地址圾亏,但是返回的內(nèi)容不一樣。當瀏覽器默認的語言為英文或者中文封拧,則會顯示對應(yīng)的英文版或者中文版的Web頁面,這種機制稱為內(nèi)容協(xié)商(Content Negotiarion)夭问。
包含在請求報文中的某些首部字段就是判斷的基準泽西。如下:
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
- Content-Language
內(nèi)容協(xié)商技術(shù)有一下三種: - 服務(wù)端驅(qū)動協(xié)商:服務(wù)端根據(jù)請求的首部字段為參考,在服務(wù)端自行處理缰趋。但對用戶來說捧杉,以瀏覽器發(fā)送的信息為為依據(jù)(一般時瀏覽器設(shè)置的語啊言等),不一定能篩選出最符合用戶的內(nèi)容
- 客戶端驅(qū)動協(xié)商: 有客戶端進行內(nèi)容協(xié)商秘血,用戶從客戶端頁面顯示可選的列表中手動選擇味抖。也可以用js腳本在頁面上自動進行選擇。比如根據(jù)設(shè)備信息自動選擇顯示PC版頁面或者H5頁面
- 透明協(xié)商:由服務(wù)器驅(qū)動和客戶端驅(qū)動的結(jié)合體灰粮。
4. 返回結(jié)果的HTTP狀態(tài)碼
狀態(tài)碼的職責是描述返回的請求結(jié)果仔涩,借助狀態(tài)碼,用戶可以知道服務(wù)器端是正常處理了請求還是出現(xiàn)了錯誤
狀態(tài)碼如 200 OK
由三位數(shù)字和原因短語組成
數(shù)字中的第一位指定了響應(yīng)的類別粘舟,響應(yīng)類別有一下5種:
僅僅記錄在RFC2616上的狀態(tài)碼就有40種熔脂。這里就介紹常用的14個狀態(tài)碼
1. 200 OK 請求正常處理
2.204 No Content 請求處理成功,但沒有資源可以返回
一般在只需要從客戶端往服務(wù)端發(fā)送消息柑肴,而對客戶端不需要發(fā)送新信息內(nèi)容的情況下使用霞揉。
3. 206 Partial Content 客戶端范圍請求,返回部分內(nèi)容
**4.301 Moved Permanently ** 永久重定向
該狀態(tài)碼表示請求的資源已經(jīng)被分配了新的URI,以后應(yīng)使用資源現(xiàn)在所指的URI,新的URI地址為Loacation首部提示的URI晰骑。
測試請求http://ymm56.com 适秩,可以看到響應(yīng)報文如下:
5. 302 Found 臨時移動
該狀態(tài)碼表示請求的資源已經(jīng)分配新的URI, 希望用戶(本次)使用新的URI訪問,與301狀態(tài)碼相似,區(qū)別就是一個是永久的一個是臨時的秽荞。以保存書簽為例骤公,如果遇到301則需要更新書簽,302則不用蚂会。
** 6.303 See Other** 查看其它位置,應(yīng)當使用GET方法獲取資源
表示由于請求對應(yīng)的資源存在著另一個URI淋样,應(yīng)使用GET方法獲取請求的資源。與302 狀態(tài)碼有相同的功能胁住,但是303狀態(tài)碼明確表示客戶端應(yīng)采用GET方法獲取資源
當301趁猴, 302,303響應(yīng)狀態(tài)碼返回時彪见,幾乎所有的瀏覽器都會把POST改成GET,并刪除請求報文內(nèi)的主體儡司,之后請求自動再次發(fā)送。
301 302標準是禁止將POST方法改成GET, 然并卵余指,實際使用時大家都會這么做
image.png
7. Not Modified : 服務(wù)端資源沒有改動捕犬,使用客戶端緩未過期的緩存
改狀態(tài)碼表示客戶端發(fā)送附帶條件的請求時,服務(wù)端允許請求訪問資源酵镜,但因發(fā)生請求未滿足條件后碉碉,直接返回304 Not Modified(服務(wù)器端資源未改變,可直接使用客戶端未過期的緩存)淮韭。304雖然被規(guī)劃到3XX垢粮,但是與重定向沒有關(guān)系。
附帶條件的請求:指的是請求采用GET方法的請求報文中包含:
If-Match
靠粪、If-Modified-Since蜡吧、If-None-Match
、If-Range占键、If-Unmodified-Since
中任一首部昔善。這里其實就是協(xié)商緩存,后面講首部的時候應(yīng)該會講到)
image.png
8. 307 Temporary Redirect: 臨時重定向
該狀態(tài)碼與302 有著相同的含義。盡管302標準禁止POST變換成GET,但是大家實際使用時并不遵守畔乙。 307會遵照瀏覽器標準君仆,不會從POST變成GET。 但是牲距,對于處理相應(yīng)時的行為袖订,每種瀏覽器有可能出現(xiàn)不同的情況。
9. 400 Bad Request: 錯誤請求
該狀態(tài)碼表示請求報文中存在語法錯誤嗅虏,服務(wù)端無法解析洛姑。錯誤發(fā)生時,客戶端需要修改請求后再次發(fā)送請求皮服。另外楞艾,瀏覽器會像200 OK 一樣對待該狀態(tài)碼参咙。
10. 401 Unauthorized:未認證
該狀態(tài)碼表示發(fā)送的請求需要通過HTTP認證的認證信息,一般指用戶需要登錄硫眯,或者登錄失敗
11. 403 Forbidden: 權(quán)限不夠
該狀態(tài)碼表示用戶的權(quán)限不夠蕴侧,無法訪問該資源。服務(wù)端沒有必要給出拒絕的詳細理由两入,如果想要做說明的話可以在主體部分對原因進行描述净宵。
12. 404 Not Found: 資源不存在
13. 405 Method Not Allowd: 方法不允許,表示請求方法錯誤
14. 500 Internal Server Error: 服務(wù)端內(nèi)部錯誤
該狀態(tài)碼表示服務(wù)端在執(zhí)行請求時出現(xiàn)錯誤裹纳,可能存在bug或者臨時故障
15. 503 Service Unavaliable: 服務(wù)不可用
該狀態(tài)碼表示服務(wù)器暫時處于超負荷狀態(tài)或者停機維護择葡,現(xiàn)在無法處理請求。如果事先得知解除以上狀況需要的時間剃氧,最好寫入Retry-After首部字段返回給客戶端
上面說明的狀態(tài)碼都是HTTP規(guī)范的敏储,但是實際開發(fā)中,很多服務(wù)端相應(yīng)的狀態(tài)碼并不會按照這個來朋鞍。比如很多web程序已添,內(nèi)部發(fā)生了錯誤,返回的狀態(tài)碼都是200 OK,在返回實體的主體中描述錯誤的原因滥酥,這種情況也是很常的更舞。
5. 與HTTP協(xié)作的Web服務(wù)器
一臺Web服務(wù)器可以搭建多個獨立域名的Web網(wǎng)站, 也可作為通信路徑上的中轉(zhuǎn)服務(wù)提升傳輸效率
5.1 使用單臺虛擬主機實現(xiàn)多個域名
一臺主體只有一個IP, 但是多個域名可以指向同一個IP. 所以可以使用一臺服務(wù)器托管多個Web服務(wù)坎吻。這就是利用了虛擬主機的功能
我個人的理解就是如果有兩個域名指向了同一個服務(wù)器缆蝉,但服務(wù)器需要提供兩個不同的服務(wù),則服務(wù)器需要根據(jù)域名創(chuàng)建不同的虛擬主機提供不同的服務(wù)禾怠,相當與Nginx中的配置多個Server綁定80端口,然后用server_name指定不同的域名地址來區(qū)分兩個不同的服務(wù)贝搁。
5.2 通信數(shù)據(jù)轉(zhuǎn)發(fā)程序: 代理吗氏、網(wǎng)關(guān)、隧道
HTTP通信時雷逆,除客戶端和服務(wù)器外弦讽,還有一些用于通信數(shù)據(jù)轉(zhuǎn)發(fā)的應(yīng)用程序,例如代理膀哲、網(wǎng)關(guān)和隧道往产。
這些應(yīng)用程序和服務(wù)器可以將請求轉(zhuǎn)發(fā)給通信線路上的下一站服務(wù)器,并能接受服務(wù)端響應(yīng)的數(shù)據(jù)再轉(zhuǎn)發(fā)給客戶端某宪。
5.2.1 代理
代理服務(wù)器的基本行為就是接受客戶端的請求后轉(zhuǎn)發(fā)給其它服務(wù)器仿村。代理不改變請求的URI,會直接發(fā)送給前方只有資源的目標服務(wù)器兴喂,從目標服務(wù)器返回的響應(yīng)也會經(jīng)過代理服務(wù)器返回給客戶端蔼囊。 代理服務(wù)器可以串聯(lián)焚志。
代理使用的理由有: 利用緩存技術(shù)介紹網(wǎng)絡(luò)帶寬、對內(nèi)部特定網(wǎng)站的訪問控制等等
代理按兩種基類分類: 是否使用緩存和是否修改報文
- 緩存代理:代理轉(zhuǎn)發(fā)響應(yīng)式畏鼓,緩存代理會預(yù)先將資源的副本保存在代理服務(wù)器上酱酬,當再次接受到對相同資源的請求時,通過判斷就可以不經(jīng)過源服務(wù)器直接響應(yīng)之前緩存的內(nèi)容云矫。
- 透明代理: 不修改請求報文的代理稱為透明代理膳沽,反之則是非透明代理
5.2.2 網(wǎng)關(guān)
網(wǎng)關(guān)的工作機制和代理非常相似,但是網(wǎng)關(guān)能時通信線路上的服務(wù)器提供非HTTP協(xié)議服務(wù)让禀。
利用網(wǎng)關(guān)能提高通信的安全性: 可以再客戶端和網(wǎng)關(guān)之間的通信線路上加密以確保連接的安全挑社。比如,網(wǎng)關(guān)也可以連接數(shù)據(jù)庫堆缘,使用SQL語句查詢數(shù)據(jù)滔灶。另外在Web購物網(wǎng)站進行信用卡核算時,網(wǎng)關(guān)可以和信用卡結(jié)算系統(tǒng)聯(lián)動吼肥。 (網(wǎng)關(guān)沒有使用過录平,后期可以配合nginx測試下網(wǎng)關(guān)的使用)
5.2.3 隧道
隧道可按要求建立起一條與其它服務(wù)器的通信線路,可以使用SSL等加密手段進行通信缀皱。隧道的目的是確倍氛猓客戶端能與服務(wù)器進行安全的通信。