前端基礎(chǔ)篇之HTTP協(xié)議

HTTP協(xié)議作為前端開(kāi)發(fā)的重要基礎(chǔ)知識(shí),卻是很多非計(jì)算機(jī)專(zhuān)業(yè)出身的碼農(nóng)的軟肋拓萌。筆者通過(guò)《圖解http》一書(shū)系統(tǒng)的學(xué)習(xí)了HTTP協(xié)議的基礎(chǔ)內(nèi)容双谆,并旁征博引渗常,試圖用更加簡(jiǎn)練的語(yǔ)言著重描述出HTTP協(xié)議需要掌握的重點(diǎn)內(nèi)容掠械,幫助不愛(ài)看書(shū)的同學(xué)節(jié)省時(shí)間由缆。

小綱老師

HTTP協(xié)議簡(jiǎn)介

《圖解HTTP》一文中這樣描述HTTP在網(wǎng)絡(luò)中的地位:

Web使用一種名為HTTP(HyperText Transfer Protocol,超文本傳輸協(xié)議)的協(xié)議作為規(guī)范猾蒂,完成從客戶(hù)端到服務(wù)器等一系列運(yùn)作流程均唉。而協(xié)議是指規(guī)則的約定』榉颍可以說(shuō)浸卦,Web是建立在HTTP協(xié)議上通信的。

HTTP協(xié)議定義Web客戶(hù)端如何從Web服務(wù)器請(qǐng)求Web頁(yè)面案糙,以及服務(wù)器如何把Web頁(yè)面?zhèn)魉徒o客戶(hù)端。HTTP協(xié)議采用了請(qǐng)求/響應(yīng)模型靴庆∈卑疲客戶(hù)端向服務(wù)器發(fā)送一個(gè)請(qǐng)求報(bào)文,請(qǐng)求報(bào)文包含請(qǐng)求的方法炉抒、URL奢讨、協(xié)議版本、請(qǐng)求頭部和請(qǐng)求數(shù)據(jù)焰薄。服務(wù)器以一個(gè)狀態(tài)行作為響應(yīng)拿诸,響應(yīng)的內(nèi)容包括協(xié)議的版本扒袖、成功或者錯(cuò)誤代碼、服務(wù)器信息亩码、響應(yīng)頭部和響應(yīng)數(shù)據(jù)季率。

HTTP是不保存狀態(tài)的協(xié)議,既無(wú)狀態(tài)協(xié)議描沟,協(xié)議本身對(duì)于請(qǐng)求或響應(yīng)之間的通信狀態(tài)不進(jìn)行保存飒泻,因此連接雙方不能知曉對(duì)方當(dāng)前的身份和狀態(tài)。這也是Cookie技術(shù)產(chǎn)生的重要原因之一:客戶(hù)端的狀態(tài)管理吏廉。瀏覽器會(huì)根據(jù)從服務(wù)器端發(fā)送的響應(yīng)報(bào)文內(nèi) Set-Cookie 首部字段信息自動(dòng)保持 Cookie泞遗。而每次客戶(hù)端發(fā)送 HTTP 請(qǐng)求,都會(huì)在請(qǐng)求報(bào)文中攜帶 Cookie席覆,作為服務(wù)端識(shí)別客戶(hù)端身份狀態(tài)的標(biāo)識(shí)史辙。

TCP/IP 協(xié)議族

為了更好的了解HTTP協(xié)議,我們必須先了解一下 TCP/IP 協(xié)議族佩伤。TCP/IP 協(xié)議族是Internet最基本的協(xié)議聊倔,HTTP協(xié)議是它的一個(gè)子集。TCP/IP協(xié)議族按層次分為以下四層(網(wǎng)絡(luò)基礎(chǔ)畦戒,最好記追娇狻):

  • 應(yīng)用層

應(yīng)用層規(guī)定了向用戶(hù)提供應(yīng)用服務(wù)時(shí)通信的協(xié)議,如:

TCP/IP 協(xié)議族內(nèi)預(yù)存了各類(lèi)通用的應(yīng)用服務(wù)協(xié)議障斋。比如纵潦,F(xiàn)TP(File Transfer Protocol,文件傳輸協(xié)議)垃环、DNS(Domain Name System邀层,域名系統(tǒng))以及HTTP協(xié)議。

DNS域名系統(tǒng)提供域名(如:https://www.baidu.com)到IP地址(如:119.75.217.109)之間的解析服務(wù)遂庄。

  • 傳輸層

傳輸層對(duì)接上層應(yīng)用層寥院,提供處于網(wǎng)絡(luò)連接中兩臺(tái)計(jì)算機(jī)之間的數(shù)據(jù)傳輸所使用的協(xié)議。

在傳輸層有兩個(gè)性質(zhì)不同的協(xié)議:TCP(Transmission Control Protocol涛目,傳輸控制協(xié)議)和UDP(User Data Protocol秸谢,用戶(hù)數(shù)據(jù)報(bào)協(xié)議)。

TCP協(xié)議是全雙工的霹肝,即發(fā)送數(shù)據(jù)和接收數(shù)據(jù)是同步進(jìn)行的估蹄,就好像我們打電話(huà)一樣,說(shuō)話(huà)的同時(shí)也能聽(tīng)見(jiàn)沫换。TCP協(xié)議在建立和斷開(kāi)連接時(shí)有三次握手和四次揮手臭蚁,因此在傳輸?shù)倪^(guò)程中更穩(wěn)定可靠但同時(shí)就沒(méi)UDP那么高效了。

UDP協(xié)議是面向無(wú)連接的,也就是說(shuō)在正式傳遞數(shù)據(jù)之前不需要先建立連接垮兑。UDP 協(xié)議不保證有序且不丟失的傳遞到對(duì)端冷尉,也就是說(shuō)不夠穩(wěn)定,但也正因如此系枪,UDP協(xié)議比TCP更加高效和輕便雀哨。

  • 網(wǎng)絡(luò)層

網(wǎng)絡(luò)層規(guī)定了數(shù)據(jù)通過(guò)怎樣的傳輸路線(xiàn)到達(dá)對(duì)方計(jì)算機(jī)傳送給對(duì)方(IP協(xié)議等)。

與對(duì)方計(jì)算機(jī)之間通過(guò)多臺(tái)計(jì)算機(jī)或網(wǎng)絡(luò)設(shè)備進(jìn)行傳輸時(shí)嗤无,網(wǎng)絡(luò)層所起的所用就是在眾多的選項(xiàng)內(nèi)選擇一條傳輸路線(xiàn)震束。就跟攜程提供的回家路線(xiàn)圖作用一樣。

  • 鏈路層

用來(lái)處理連接網(wǎng)絡(luò)的硬件部分当犯,包括控制操作系統(tǒng)垢村、硬件的設(shè)備驅(qū)動(dòng)、NIC(Network Interface Card嚎卫,網(wǎng)絡(luò)適配器嘉栓,即網(wǎng)卡),及光纖等物理可見(jiàn)部分(還包括連接器等一切傳輸媒介)拓诸。硬件上的范疇均在鏈路層的作用范圍之內(nèi)侵佃。

一般的web應(yīng)用的通信傳輸流是這樣的:

發(fā)送端在層與層之間傳輸數(shù)據(jù)時(shí),每經(jīng)過(guò)一層時(shí)會(huì)被打上一個(gè)該層所屬的首部信息奠支。反之馋辈,接收端在層與層之間傳輸數(shù)據(jù)時(shí),每經(jīng)過(guò)一層時(shí)會(huì)把對(duì)應(yīng)的首部信息去除倍谜。

串行連接迈螟、持久連接、管道化持久連接尔崔、http/2.0多路復(fù)用簡(jiǎn)介

  • 串行連接: HTTP有無(wú)連接的特性答毫,即每次連接只能處理一個(gè)請(qǐng)求季春,收到響應(yīng)后立即斷開(kāi)連接。HTTP/1.0 版本(稱(chēng)為串行連接或短連接耘拇、短輪詢(xún))中每次HTTP通信后都要斷開(kāi)TCP連接,所以每個(gè)新的HTTP請(qǐng)求都需要建立一個(gè)新的連接宇攻。但在現(xiàn)在網(wǎng)站動(dòng)則幾十條HTTP請(qǐng)求的情況下驼鞭,很容易達(dá)到瀏覽器請(qǐng)求上限,并且每次請(qǐng)求都建立新的tcp連接(每次都有三次握手四次揮別)極大的增加了通信開(kāi)銷(xiāo)尺碰。
  • 持久連接: 為解決這個(gè)問(wèn)題,有人提出了持久連接(也叫長(zhǎng)連接、長(zhǎng)輪詢(xún))亲桥。一定時(shí)間內(nèi)洛心,同一域名下的HTTP請(qǐng)求,只要兩端都沒(méi)有提出斷開(kāi)連接题篷,則持久保持TCP連接狀態(tài)词身,其他請(qǐng)求可以復(fù)用這個(gè)連接通道。HTTP/1.1 實(shí)現(xiàn)并默認(rèn)了所有連接都是持久連接番枚,這樣客戶(hù)端發(fā)起多個(gè)HTTP請(qǐng)求時(shí)就減少了TCP握手造成的網(wǎng)絡(luò)資源和通信時(shí)間的浪費(fèi)法严。但是持久連接采用阻塞模式,下次請(qǐng)求必須等到上次響應(yīng)返回后才能發(fā)起葫笼,如果上次的請(qǐng)求還沒(méi)返回響應(yīng)內(nèi)容深啤,下次請(qǐng)求就只能等著(就是常說(shuō)的線(xiàn)頭阻塞)。
  • 管道化持久連接: 管道化則可以不用等待響應(yīng)返回而發(fā)送下個(gè)請(qǐng)求并按順序返回響應(yīng)路星,現(xiàn)代瀏覽器并未默認(rèn)開(kāi)啟管道化溯街。(這方面收集到的資料有限不多說(shuō)了)
  • HTTP/2.0多路復(fù)用: 每個(gè)HTTP請(qǐng)求都有一個(gè)序列標(biāo)識(shí)符,這樣瀏覽器可以并發(fā)多個(gè)請(qǐng)求洋丐,服務(wù)器接收到數(shù)據(jù)后呈昔,再根據(jù)序列標(biāo)識(shí)符重新排序成不同的請(qǐng)求報(bào)文堤尾,而不會(huì)導(dǎo)致數(shù)據(jù)錯(cuò)亂( 細(xì)節(jié)參照此文)郭宝。同樣剩蟀,服務(wù)端也可以并發(fā)返回多個(gè)響應(yīng)給瀏覽器,瀏覽器收到后根據(jù)序列標(biāo)識(shí)重新排序并歸入各自的請(qǐng)求的響應(yīng)報(bào)文缰冤。并且同一個(gè)域名下的所有請(qǐng)求都復(fù)用同一個(gè)TCP連接棉浸,極大增加了服務(wù)器處理并發(fā)的上限迷郑。
  • WebSocket: WebSocket是HTML5提出的一種客戶(hù)端和服務(wù)端通訊的全雙工協(xié)議嗡害,由客戶(hù)端發(fā)起請(qǐng)求霸妹,建立連接之后不僅客戶(hù)端可以主動(dòng)向服務(wù)端發(fā)送請(qǐng)求鹃骂,服務(wù)端可以主動(dòng)向客戶(hù)端推送信息畏线。

看圖區(qū)分三種鏈接:

如圖中(a):串行連接每次發(fā)起請(qǐng)求都必須建立新的tcp連接象踊。

如圖中(b):持久連接多個(gè)http請(qǐng)求可以復(fù)用同一個(gè)tcp連接,但是下次請(qǐng)求必須在上次響應(yīng)返回之后進(jìn)行史隆。

如圖中(c):管道化持久連接也可以復(fù)用同一個(gè)tcp連接曼验,并且可以不用等待發(fā)出多個(gè)http請(qǐng)求熔酷,但是響應(yīng)必須按順序返回拒秘。

URI

HTTP協(xié)議使用 URI 定位互聯(lián)網(wǎng)上的資源躺酒。概念:

  • URI(Universal Resource Identifier:統(tǒng)一資源標(biāo)識(shí)符)
  • URL(Universal Resource Locator:統(tǒng)一資源定位符)
  • URN(Universal Resource Name:統(tǒng)一資源名稱(chēng))羹应。

個(gè)人理解URI是一個(gè)資源文件的不同表示方法的總稱(chēng)雳刺。比如一個(gè)文件 a.html 煞烫,既可以用這個(gè)文件的名字 a.html 來(lái)表示,也可以用文件路徑 www.baidu.com/a.html 來(lái)表示紊馏,甚至可以用 urn:a:1535-3613 這樣的標(biāo)識(shí)符來(lái)表示。他們的關(guān)系如下:

HTTP版本

對(duì)于HTTP版本更詳細(xì)的區(qū)別赫编,筆者不才擂送,請(qǐng)參考這篇文章

HTTP/1.0

最早的http只是使用在一些較為簡(jiǎn)單的網(wǎng)頁(yè)上和網(wǎng)絡(luò)請(qǐng)求上,所以比較簡(jiǎn)單蟀拷,每次請(qǐng)求都打開(kāi)一個(gè)新的TCP鏈接问芬,收到響應(yīng)之后立即斷開(kāi)連接。

HTTP/1.1

  • HTTP/1.1 引入了更多的緩存控制策略炕柔,如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等
  • HTTP/1.1 允許范圍請(qǐng)求欢嘿,即在請(qǐng)求頭中加入Range頭部
  • HTTP/1.1 的請(qǐng)求消息和響應(yīng)消息都必須包含Host頭部炼蹦,以區(qū)分同一個(gè)物理主機(jī)中的不同虛擬主機(jī)的域名
  • HTTP/1.1 默認(rèn)開(kāi)啟持久連接狗热,在一個(gè)TCP連接上可以傳送多個(gè)HTTP請(qǐng)求和響應(yīng)匿刮,減少了建立和關(guān)閉連接的消耗和延遲。

HTTP/2.0

在 HTTP/2 中光羞,有兩個(gè)非常重要的概念纱兑,分別是幀(frame)和流(stream),理解這兩個(gè)概念是理解下面多路復(fù)用的前提笛匙。 幀代表數(shù)據(jù)傳輸?shù)淖钚〉膯挝煌衍裕總€(gè)幀都有序列標(biāo)識(shí)表明該幀屬于哪個(gè)流必怜,流也就是多個(gè)幀組成的數(shù)據(jù)流,每個(gè)流表示一個(gè)請(qǐng)求鳞溉。這里有個(gè)chrome擴(kuò)展程序看政,可以方便的查看當(dāng)前網(wǎng)站的HTTP請(qǐng)求版本(安裝后在chrome開(kāi)發(fā)工具-Network-在Name/Size/Time表格頭右鍵選擇Procotol于颖,即可查看協(xié)議版本)。

  • 新的二進(jìn)制格式: HTTP/1.x的解析是基于文本的章母。基于文本協(xié)議的解析存在天然缺陷,文本的表現(xiàn)形式有多樣性恕出,要做到全面性考慮的場(chǎng)景必然很多。二進(jìn)制則不同的畴,只識(shí)別0和1的組合〖褰浚基于這種考慮HTTP/2.0的協(xié)議解析采用二進(jìn)制格式缓呛,方便且強(qiáng)大寺渗。
  • 多路復(fù)用: HTTP/2.0支持多路復(fù)用匿情,這是HTTP/1.1持久連接的升級(jí)版兰迫。多路復(fù)用,就是在一個(gè) TCP 連接中可以存在多條流炬称,也就是可以發(fā)送多個(gè)請(qǐng)求汁果,服務(wù)端則可以通過(guò)幀中的標(biāo)識(shí)知道該幀屬于哪個(gè)流(即請(qǐng)求),通過(guò)重新排序還原請(qǐng)求玲躯。多路復(fù)用允許并發(fā)的發(fā)起多個(gè)請(qǐng)求,每個(gè)請(qǐng)求及該請(qǐng)求的響應(yīng)不需要等待其他的請(qǐng)求或響應(yīng),避免了線(xiàn)頭阻塞問(wèn)題。這樣某個(gè)請(qǐng)求任務(wù)耗時(shí)嚴(yán)重或渤,不會(huì)影響到其它連接的正常執(zhí)行,極大的提高傳輸性能池磁。
  • 頭部壓縮: HTTP/1.x的請(qǐng)求和響應(yīng)頭部帶有大量信息银舱,而且每次請(qǐng)求都要重復(fù)發(fā)送,HTTP/2.0使用encoder來(lái)減少需要傳輸?shù)念^部大小粉寞,通訊雙方各自cache一份頭部 fields表,既避免了重復(fù)頭部的傳輸澎怒,又減小了需要傳輸?shù)拇笮 ?/li>
  • 服務(wù)端推送: 這里的服務(wù)端推送指把客戶(hù)端所需要的css/js/img資源伴隨著index.html一起發(fā)送到客戶(hù)端,省去了客戶(hù)端重復(fù)請(qǐng)求的步驟(從緩存中取)。

HTTP/3.0

HTTP/2.0 使用了多路復(fù)用莱睁,一般來(lái)說(shuō)同一域名下只需要使用一個(gè) TCP 連接琳彩。但當(dāng)這個(gè)連接中出現(xiàn)了丟包的情況箱锐,那就會(huì)導(dǎo)致整個(gè) TCP 都要開(kāi)始等待重傳嫂便,也就導(dǎo)致了后面的所有數(shù)據(jù)都被阻塞了凸丸。反而對(duì)于 HTTP/1.0 來(lái)說(shuō),可以開(kāi)啟多個(gè) TCP 連接复哆,出現(xiàn)丟包反倒只會(huì)影響其中一個(gè)連接,剩余的 TCP 連接還可以正常傳輸數(shù)據(jù)嘹裂。 出現(xiàn)包阻塞的原因是因?yàn)榈讓覶CP協(xié)議導(dǎo)致的問(wèn)題泊愧,但是修改TCP協(xié)議是不現(xiàn)實(shí)的問(wèn)題敲街,就像typeof null === 'object'一樣,修改這個(gè)問(wèn)題會(huì)導(dǎo)致出現(xiàn)更多的問(wèn)題萧豆。既然不能修改你,那就另起一個(gè)協(xié)議取代你览爵。Google 基于 UDP 協(xié)議推出了一個(gè)的 QUIC 協(xié)議,并且使用在了 HTTP/3 上。

QUIC 基于 UDP希太,但是UDP本身存在不穩(wěn)定性等諸多問(wèn)題,所以QUIC在UDP的基礎(chǔ)上新增了很多功能崔泵,比如多路復(fù)用、0-RTT憎瘸、使用 TLS1.3 加密入篮、流量控制、有序交付幌甘、重傳等等功能潮售。優(yōu)點(diǎn)諸多痊项,參考這里

  • 避免包阻塞: 多個(gè)流的數(shù)據(jù)包在TCP連接上傳輸時(shí),若一個(gè)流中的數(shù)據(jù)包傳輸出現(xiàn)問(wèn)題饲做,TCP需要等待該包重傳后线婚,才能繼續(xù)傳輸其它流的數(shù)據(jù)包。但在基于UDP的QUIC協(xié)議中盆均,不同的流之間的數(shù)據(jù)傳輸真正實(shí)現(xiàn)了相互獨(dú)立互不干擾塞弊,某個(gè)流的數(shù)據(jù)包在出問(wèn)題需要重傳時(shí),并不會(huì)對(duì)其他流的數(shù)據(jù)包傳輸產(chǎn)生影響泪姨。
  • 快速重啟會(huì)話(huà): 普通基于tcp的連接游沿,是基于兩端的ip和端口和協(xié)議來(lái)建立的。在網(wǎng)絡(luò)切換場(chǎng)景肮砾,例如手機(jī)端切換了無(wú)線(xiàn)網(wǎng)诀黍,使用4G網(wǎng)絡(luò),會(huì)改變本身的ip仗处,這就導(dǎo)致tcp連接必須重新創(chuàng)建眯勾。而QUIC協(xié)議使用特有的UUID來(lái)標(biāo)記每一次連接,在網(wǎng)絡(luò)環(huán)境發(fā)生變化的時(shí)候婆誓,只要UUID不變吃环,就能不需要握手,繼續(xù)傳輸數(shù)據(jù)洋幻。

HTTP報(bào)文

用于HTTP協(xié)議交互的信息被稱(chēng)為HTTP報(bào)文郁轻。客戶(hù)端的HTTP報(bào)文叫請(qǐng)求報(bào)文文留,服務(wù)端的HTTP報(bào)文叫響應(yīng)報(bào)文好唯。

請(qǐng)求報(bào)文 是由請(qǐng)求行(請(qǐng)求方法、協(xié)議版本)燥翅、請(qǐng)求首部(請(qǐng)求URI骑篙、客戶(hù)端信息等)和內(nèi)容實(shí)體(用戶(hù)信息和資源信息等,可為空)構(gòu)成森书。

響應(yīng)報(bào)文 是由狀態(tài)行(協(xié)議版本替蛉、狀態(tài)碼)、響應(yīng)首部(服務(wù)器名稱(chēng)拄氯、資源標(biāo)識(shí)等)和內(nèi)容實(shí)體(服務(wù)端返回的資源信息)構(gòu)成。

請(qǐng)求方法

  • GET:get方法一般用于獲取服務(wù)器資源
  • POST:post方法一般用于傳輸實(shí)體主體
  • PUT:put方法一般用于傳輸文件
  • DELETE:delete方法用于刪除文件
  • HEAD:head方法用于獲取報(bào)文首部它浅,不返回報(bào)文主體
  • OPTIONS:options方法用于詢(xún)問(wèn)請(qǐng)求URI資源支持的方法

概念很簡(jiǎn)單很精辟译柏,還不太理解應(yīng)用場(chǎng)景的自行百度~~

狀態(tài)碼

HTTP狀態(tài)碼表示客戶(hù)端HTTP請(qǐng)求的返回結(jié)果、標(biāo)識(shí)服務(wù)器處理是否正常姐霍、表明請(qǐng)求出現(xiàn)的錯(cuò)誤等鄙麦。


image.png

首部字段

下面是請(qǐng)求首部和響應(yīng)首部中的字段名稱(chēng)和作用:






首部?jī)?nèi)容較多典唇,重點(diǎn)記憶瀏覽器常用的一些字段就行了:


兩種請(qǐng)求

瀏覽器發(fā)送 CORS 請(qǐng)求(跨域請(qǐng)求)時(shí), 會(huì)將請(qǐng)求分為簡(jiǎn)單請(qǐng)求與復(fù)雜請(qǐng)求.
在我們?nèi)粘9ぷ髦? 常用的簡(jiǎn)單請(qǐng)求可以將其歸為以下幾點(diǎn):

1.請(qǐng)求的方法只能為HEAD、GET胯府、POST
2.無(wú)自定義請(qǐng)求頭
3.Content-Type只能是這幾種:
text/plain介衔、multipart/form-data、application/x-www-form-urlencoded

復(fù)雜請(qǐng)求:

1.PUT, Delete 方法的 ajax 請(qǐng)求
2.發(fā)送 JSON 格式的 ajax 請(qǐng)求(比如post數(shù)據(jù))
3.帶自定義頭的 ajax 請(qǐng)求

如果是簡(jiǎn)單請(qǐng)求, 則會(huì)先執(zhí)行, 后判斷骂因。執(zhí)行的過(guò)程大致如下:
瀏覽器檢測(cè)到請(qǐng)求是 CORS 請(qǐng)求, 添加一個(gè)origin字段(其中包含頁(yè)面源信息: 協(xié)議炎咖、域名、端口) ====> 服務(wù)端收到后作相應(yīng)的處理(對(duì)比origin, 服務(wù)端判斷這個(gè)源是否接受)返回結(jié)果給瀏覽器 ====> 瀏覽器檢查響應(yīng)頭是否允許跨域信息 ====> 允許, 那就當(dāng)做沒(méi)事發(fā)生寒波。 不允許, 瀏覽器拋出相應(yīng)的錯(cuò)誤信息乘盼。
復(fù)雜請(qǐng)求在發(fā)生請(qǐng)求時(shí), 如果是 CORS 請(qǐng)求,瀏覽器預(yù)先發(fā)送一個(gè) option 請(qǐng)求俄烁。瀏覽器這種行為被稱(chēng)之為預(yù)檢請(qǐng)求(注意如果不是跨域請(qǐng)求就不會(huì)發(fā)生預(yù)檢請(qǐng)求绸栅,比如反向代理)。

WEB服務(wù)器

這里不關(guān)心服務(wù)器是Apache還是Nginx页屠,而是在于服務(wù)器的作用粹胯。一臺(tái)服務(wù)器可以作為源服務(wù)器,也可以作為中轉(zhuǎn)服務(wù)器辰企,甚至可以在一臺(tái)服務(wù)器上搭建多個(gè)不同域名的網(wǎng)站风纠。

虛擬主機(jī)

HTTP/1.1規(guī)范允許一臺(tái)HTTP服務(wù)器搭建多個(gè)Web站點(diǎn)。利用虛擬主機(jī)的功能蟆豫,可以在一臺(tái)物理服務(wù)器(一個(gè)IP地址)上虛擬出多個(gè)主機(jī)议忽,每個(gè)主機(jī)映射一個(gè)獨(dú)立的域名。因此十减,當(dāng)用戶(hù)訪(fǎng)問(wèn)域名http://www.laogeng.com/時(shí)栈幸,DNS域名系統(tǒng)會(huì)將其解析成IP地址,根據(jù)IP找到物理服務(wù)器帮辟,然后再通過(guò)請(qǐng)求首部的HOST字段(現(xiàn)在知道HOST為什么是HTTP/1.1強(qiáng)制要求攜帶的了吧)確認(rèn)對(duì)應(yīng)的虛擬主機(jī)速址。

代理服務(wù)器

代理服務(wù)器就是客戶(hù)端和服務(wù)端之間的“中間商”,即HTTP請(qǐng)求通過(guò)代理服務(wù)器轉(zhuǎn)發(fā)給服務(wù)器由驹,再將服務(wù)器的響應(yīng)返回給客戶(hù)端的行為芍锚。代理服務(wù)器可以用來(lái)作為緩存服務(wù)器,也可以用來(lái)隱藏用戶(hù)身份(正向代理)或者服務(wù)器身份(反向代理)增加安全性蔓榄。

  • 所謂正向代理并炮,是從客戶(hù)/客戶(hù)端角度出發(fā),為了從源服務(wù)器中取得內(nèi)容甥郑,由客戶(hù)端向代理服務(wù)器發(fā)出請(qǐng)求逃魄,并指定目標(biāo)訪(fǎng)問(wèn)服務(wù)器,然后澜搅,代理服務(wù)器向源服務(wù)器轉(zhuǎn)交需求伍俘,并將獲得的內(nèi)容返回給客戶(hù)端邪锌。需要注意的是,在正向代理過(guò)程中隱藏了真是請(qǐng)求的客戶(hù)端癌瘾,即服務(wù)端不知道正式請(qǐng)求客戶(hù)是誰(shuí)觅丰。(科學(xué)上網(wǎng))

  • 所謂反向代理,是從客戶(hù)端發(fā)向反向代理出請(qǐng)求妨退,反向代理服務(wù)器收到需求后判斷請(qǐng)求走向何處妇萄,然后再將結(jié)果反饋給客戶(hù)端。同樣需要注意的是碧注,在反向代理過(guò)程中嚣伐,隱藏了內(nèi)部服務(wù)器的信息,用戶(hù)不需要知道是具體哪一臺(tái)服務(wù)器提供的服務(wù)萍丐,只要知道反向代理服務(wù)器是誰(shuí)就好了轩端,我們甚至可以把反向代理服務(wù)器當(dāng)做真正服務(wù)器看待。這種形式的代理通常被用作實(shí)現(xiàn)負(fù)載均衡逝变,比如Nginx就是一種出色的反向代理服務(wù)器基茵。

  • 反向代理解決跨域問(wèn)題:我們前端在使用 vue-cli 這種腳手架工具進(jìn)行開(kāi)發(fā)時(shí),經(jīng)常會(huì)遇到跨域的問(wèn)題壳影,因?yàn)轫?xiàng)目自身啟動(dòng)本地服務(wù)是需要占用一個(gè)端口(如 http://localhost:8080)的拱层,所以必然會(huì)產(chǎn)生跨域的問(wèn)題(因?yàn)楸镜胤?wù)端口和服務(wù)端接口地址不是同源)。在使用webpack做構(gòu)建工具的項(xiàng)目中宴咧,經(jīng)常會(huì)使用proxyTable代理實(shí)現(xiàn)跨域(具體實(shí)現(xiàn)自行百度)根灯。之所以出現(xiàn)跨域是因?yàn)闉g覽器有同源策略的限制,但服務(wù)器是沒(méi)有的同源策略的限制的掺栅。當(dāng)我們本地服務(wù)(假設(shè)域名:http://localhost:8080)要請(qǐng)求目標(biāo)服務(wù)器(假設(shè)域名:http://target.com)的資源的時(shí)候烙肺,我們不直接請(qǐng)求 target.com,而是請(qǐng)求本地服務(wù)自身 http://localhost:8080(這時(shí)是同源請(qǐng)求氧卧,不存在跨域)桃笙,本地代理服務(wù)再將接口轉(zhuǎn)發(fā)給 target.com(注意這時(shí)候是兩個(gè)服務(wù)器直接的通信了,而不是客戶(hù)端和服務(wù)器的通信沙绝,所以更不存在跨域)搏明,本地服務(wù)獲取到目標(biāo)服務(wù)器的響應(yīng)數(shù)據(jù)之后通過(guò)再代理偽裝成本地服務(wù)請(qǐng)求的返回值返回給客戶(hù)端。

    本地服務(wù)在瀏覽器向本地服務(wù)發(fā)起請(qǐng)求 --> 本地代理轉(zhuǎn)發(fā) --> 目標(biāo)服務(wù)器 --> 響應(yīng)數(shù)據(jù)后通過(guò)代理偽裝成本地服務(wù)器請(qǐng)求的返回值 --> 瀏覽器接受到目標(biāo)服務(wù)器的數(shù)據(jù)

vue-cli反向代理配置如下:

//vue.config.js
  ......
  devServer: {
    port: 8080, // 配置端口
    open: true, // 項(xiàng)目啟動(dòng)自動(dòng)開(kāi)啟瀏覽器
    compress: true, // 開(kāi)啟壓縮
    overlay: { // 設(shè)置讓瀏覽器 overlay 同時(shí)顯示警告和錯(cuò)誤
      warnings: true,
      errors: true
    },
    // 設(shè)置請(qǐng)求反向代理
    proxy: {
      '/api': { // 要代理的接口的匹配字符
        target: process.env.BASE_URL, // 接口域名
        secure: false,
        changeOrigin: true
      }
    }
  },
  ......

需要注意如果要用反向代理闪檬,則在 axios 配置的時(shí)候星著,請(qǐng)求baseURL必須設(shè)置為字符串'/',否則 proxy 會(huì)匹配不到'/api'導(dǎo)致代理失敗粗悯。

緩存服務(wù)器

緩存服務(wù)器指的是將需要頻繁訪(fǎng)問(wèn)的網(wǎng)絡(luò)內(nèi)容存放在離用戶(hù)較近虚循、訪(fǎng)問(wèn)速度更快的服務(wù)器中,以提高內(nèi)容訪(fǎng)問(wèn)速度的一種技術(shù)为黎。緩存服務(wù)器是瀏覽器和源服務(wù)器之間的中間服務(wù)器邮丰,瀏覽器先向這個(gè)中間服務(wù)器發(fā)起HTTP請(qǐng)求,經(jīng)過(guò)處理后(比如權(quán)限驗(yàn)證铭乾,緩存匹配等)剪廉,再將請(qǐng)求轉(zhuǎn)發(fā)到源服務(wù)器。

HTTPS

HTTP本身沒(méi)有任何保密性炕檩,所以HTTP傳輸?shù)臄?shù)據(jù)相當(dāng)于都是在網(wǎng)上在以明文的方式裸奔斗蒋。為了解決這個(gè)問(wèn)題,出現(xiàn)了各種加密技術(shù):

  • 對(duì)稱(chēng)加密:唯一密鑰key1可用來(lái)加密也可用來(lái)解密笛质。這樣的加密需要雙方都擁有密鑰key1泉沾,如果第一次傳輸密鑰被第三方截獲就玩完。

  • 非對(duì)稱(chēng)加密:公鑰key3和私鑰key2都可用于對(duì)應(yīng)的加密和解密妇押,即可用公鑰加密私鑰解密跷究,也可用私鑰加密公鑰解密。服務(wù)端會(huì)生成一對(duì)密鑰敲霍,一個(gè)私鑰保存在服務(wù)端俊马,僅自己知道,另一個(gè)是公鑰肩杈,公鑰可以自由發(fā)布供任何人使用柴我。客戶(hù)端的明文通過(guò)公鑰加密后的密文需要用私鑰解密扩然。非對(duì)稱(chēng)密鑰在加密和解密的過(guò)程的使用的密鑰是不同的密鑰艘儒,加密和解密是不對(duì)稱(chēng)的,所以稱(chēng)之為非對(duì)稱(chēng)加密夫偶。與對(duì)稱(chēng)密鑰加密相比界睁,非對(duì)稱(chēng)加密無(wú)需在客戶(hù)端和服務(wù)端之間共享密鑰,只要私鑰不發(fā)給任何用戶(hù)索守,即使公鑰在網(wǎng)上被截獲晕窑,也無(wú)法被解密,僅有被竊取的公鑰是沒(méi)有任何用處的卵佛。

  • 混合加密:服務(wù)端先用非對(duì)稱(chēng)加密的私鑰key2加密對(duì)稱(chēng)加密的密鑰key1并傳給客戶(hù)端杨赤,客戶(hù)端用非對(duì)稱(chēng)加密的公鑰key3解密出對(duì)稱(chēng)加密的密鑰key1,雙方都有了密鑰key1截汪,開(kāi)始利用key1加密通信疾牲。缺點(diǎn):中間人可以自己生成非對(duì)稱(chēng)加密公鑰替換掉服務(wù)端公鑰發(fā)送給客戶(hù)端,而此時(shí)客戶(hù)端并無(wú)法驗(yàn)證公鑰的可信性衙解。

  • SSL:首先需要從證書(shū)認(rèn)證機(jī)構(gòu)申請(qǐng)證書(shū)(證書(shū)中含有證書(shū)簽名和服務(wù)端公鑰key3)阳柔。在客戶(hù)端發(fā)起HTTP請(qǐng)求時(shí),服務(wù)端將證書(shū)發(fā)送給客戶(hù)端蚓峦∩嗉粒客戶(hù)端認(rèn)證證書(shū)的真?zhèn)渭贸缓蠼饷艹龇?wù)端公鑰key3,用公鑰加密自己生成的對(duì)稱(chēng)加密密鑰key1并傳給服務(wù)端霍转,最后利用key1加密進(jìn)行通話(huà)荐绝。至于安全性,由于私鑰是機(jī)構(gòu)的避消,可以避免第三方偽造證書(shū)低滩。并且就算得到了服務(wù)端公鑰,也無(wú)法解密出公鑰key3加密過(guò)的對(duì)稱(chēng)加密密鑰key1岩喷。

    image.png

    HTTPS基于HTTP協(xié)議恕沫,通過(guò)SSL或TLS(可以看作SSL3.0)提供加密處理數(shù)據(jù)、驗(yàn)證對(duì)方身份以及數(shù)據(jù)完整性保護(hù)纱意。特點(diǎn)如下:

  • 內(nèi)容加密:采用混合加密技術(shù)婶溯,中間者無(wú)法直接查看明文內(nèi)容

  • 驗(yàn)證身份:通過(guò)證書(shū)認(rèn)證客戶(hù)端訪(fǎng)問(wèn)的是自己的服務(wù)器

  • 保護(hù)數(shù)據(jù)完整性:防止傳輸?shù)膬?nèi)容被中間人冒充或者篡改

HTTPS和HTTP的區(qū)別主要如下:

  1. HTTPS協(xié)議需要到CA(證書(shū)頒發(fā)機(jī)構(gòu))申請(qǐng)證書(shū),一般免費(fèi)證書(shū)很少妇穴,需要交費(fèi)爬虱。
  2. HTTP協(xié)議運(yùn)行在TCP之上,所有傳輸?shù)膬?nèi)容都是明文腾它,HTTPS運(yùn)行在SSL/TLS之上跑筝,SSL/TLS運(yùn)行在TCP之上,所有傳輸?shù)膬?nèi)容都經(jīng)過(guò)加密的瞒滴。
  3. HTTP和HTTPS使用的是完全不同的連接方式曲梗,用的端口也不一樣,前者是80妓忍,后者是443虏两。
  4. http的連接很簡(jiǎn)單,是無(wú)狀態(tài)的世剖;HTTPS協(xié)議是由HTTP+SSL協(xié)議構(gòu)建的可進(jìn)行加密傳輸定罢、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,可以有效的防止運(yùn)營(yíng)商劫持旁瘫,解決了防劫持的一個(gè)大問(wèn)題祖凫,比http協(xié)議安全。

WEB安全防范

XSS 攻擊

XSS 攻擊全稱(chēng)跨站腳本攻擊酬凳,是利用html可以執(zhí)行<script>alert(1)</script>的特性惠况,想盡辦法將腳本注入頁(yè)面中的攻擊手段。XSS攻擊有兩種宁仔,一種是通過(guò)修改瀏覽器URL導(dǎo)致腳本被注入到頁(yè)面稠屠,另一種是通過(guò)輸入框?qū)⒛_本代碼注入數(shù)據(jù)庫(kù)。前面一種會(huì)被chrome瀏覽器自動(dòng)防御攻擊(但最好還是手動(dòng)也防御一下),后面一種則需要我們手動(dòng)防御权埠,推薦使用'xss'庫(kù)的白名單過(guò)濾防御方法:

const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1>&lt;script&gt;alert("xss");&lt;/script&gt;

CSRF 攻擊

CSRF中文名為跨站請(qǐng)求偽造榨了。假如掘金有個(gè)加關(guān)注的GET接口,id參數(shù)是關(guān)注人Id攘蔽,如下:

https://juejin.im?id=5cd0438c6fb9a031ec6d3ab2

那我只需要在我的一個(gè)頁(yè)面里面寫(xiě)一個(gè)img標(biāo)簽:

<img src="https://juejin.im?id=5cd0438c6fb9a031ec6d3ab2" />

那么只要有已經(jīng)登錄掘金的用戶(hù)打開(kāi)我這個(gè)頁(yè)面阻逮,就會(huì)自動(dòng)關(guān)注我。 就算是改為POST請(qǐng)求秩彤,也可以通過(guò)在頁(yè)面使用form表單提交的方式自動(dòng)關(guān)注。 CSRF攻擊是源于Web的隱式身份驗(yàn)證機(jī)制事哭!Web的身份驗(yàn)證機(jī)制雖然可以保證一個(gè)請(qǐng)求是來(lái)自于某個(gè)用戶(hù)的瀏覽器漫雷,但卻無(wú)法保證該請(qǐng)求是用戶(hù)批準(zhǔn)發(fā)送的。CSRF攻擊的問(wèn)題一般是由服務(wù)端解決鳍咱,防范 CSRF 攻擊可以遵循以下幾種規(guī)則:

  1. Get 請(qǐng)求不用于對(duì)數(shù)據(jù)進(jìn)行修改
  2. Cookie設(shè)置HTTP Only
  3. 接口設(shè)置禁止跨域
  4. 請(qǐng)求時(shí)附帶驗(yàn)證信息降盹,比如驗(yàn)證碼或者 Token

點(diǎn)擊劫持

點(diǎn)擊劫持是一種視覺(jué)欺騙的攻擊手段。攻擊者將需要攻擊的網(wǎng)站通過(guò) iframe 嵌入自己的網(wǎng)頁(yè)中谤辜,并將 iframe 設(shè)置為透明蓄坏,然后誘使用戶(hù)在該頁(yè)面上進(jìn)行操作,此時(shí)用戶(hù)將在不知情的情況下點(diǎn)擊透明的iframe頁(yè)面(偸yck大佬一張圖會(huì)不會(huì)被抓┭┮﹏┭┮):

防御方法:

還是讓后端大佬解決丑念,使用一個(gè)HTTP響應(yīng)頭——X-Frame-Options涡戳。X-Frame-Options可以說(shuō)是為了解決點(diǎn)擊劫持而生的,它有三個(gè)可選的值:

  1. DENY:瀏覽器會(huì)拒絕當(dāng)前頁(yè)面加載任何frame頁(yè)面脯倚;
  2. SAMEORIGIN:frame頁(yè)面的地址只能為同源域名下的頁(yè)面渔彰;
  3. ALLOW-FROM origin:允許frame加載的頁(yè)面地址;

中間人攻擊

中間人攻擊是攻擊方同時(shí)與服務(wù)端和客戶(hù)端建立起了連接推正,并讓對(duì)方認(rèn)為連接是安全的恍涂,但是實(shí)際上整個(gè)通信過(guò)程都被攻擊者控制了。攻擊者不僅能獲得雙方的通信信息植榕,還能修改通信信息再沧。中間人攻擊的本質(zhì)是客戶(hù)端和服務(wù)端之間的認(rèn)證和信任問(wèn)題。

對(duì)稱(chēng)加密尊残、非對(duì)稱(chēng)加密炒瘸、混合加密技術(shù)都沒(méi)有有效防止中間人攻擊,因?yàn)橹虚g人可以截取首次傳輸?shù)拿荑€并偷天換日夜郁,而客戶(hù)端或服務(wù)端并無(wú)法得知什燕。HTTPS作為防止中間人攻擊的終極手段,引入證書(shū)機(jī)制解決了客戶(hù)端和服務(wù)端的信任問(wèn)題竞端,從而較為有效的防止了中間人攻擊屎即。

小結(jié)

以上就是前端需要掌握的HTTP相關(guān)知識(shí)點(diǎn),能力所限部分知識(shí)點(diǎn)講述可能不甚清晰,還請(qǐng)看官們有不清楚的地方直接批評(píng)改正技俐。

前端是一門(mén)龐大的學(xué)科乘陪,雖然對(duì)入門(mén)門(mén)檻要求不高,但是其知識(shí)體系之龐大讓人望洋興嘆雕擂。小子作為半路出家的前端小白啡邑,打算按照大牛的 指點(diǎn)(感謝) 從頭開(kāi)始學(xué)習(xí)前端,每學(xué)一個(gè)知識(shí)點(diǎn)都會(huì)作篇總結(jié)井赌,加深自己理解并方便他人查閱谤逼。

推薦閱讀另一篇有關(guān)http協(xié)議的文章HTTP 協(xié)議超級(jí)詳解,對(duì) HTTP 的講解更詳細(xì)仇穗。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末流部,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子纹坐,更是在濱河造成了極大的恐慌枝冀,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耘子,死亡現(xiàn)場(chǎng)離奇詭異果漾,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)谷誓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)绒障,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人捍歪,你說(shuō)我怎么就攤上這事端盆。” “怎么了费封?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵焕妙,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我弓摘,道長(zhǎng)焚鹊,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任韧献,我火速辦了婚禮末患,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘锤窑。我一直安慰自己璧针,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布渊啰。 她就那樣靜靜地躺著探橱,像睡著了一般申屹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上隧膏,一...
    開(kāi)封第一講書(shū)人閱讀 52,328評(píng)論 1 310
  • 那天哗讥,我揣著相機(jī)與錄音,去河邊找鬼胞枕。 笑死杆煞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的腐泻。 我是一名探鬼主播决乎,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼派桩!你這毒婦竟也來(lái)了瑞驱?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤窄坦,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后凳寺,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鸭津,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年肠缨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逆趋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晒奕,死狀恐怖闻书,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情脑慧,我是刑警寧澤魄眉,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站闷袒,受9級(jí)特大地震影響坑律,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜囊骤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一晃择、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧也物,春花似錦宫屠、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)抵栈。三九已至,卻和暖如春乌逐,著一層夾襖步出監(jiān)牢的瞬間竭讳,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工浙踢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绢慢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓洛波,卻偏偏與公主長(zhǎng)得像胰舆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蹬挤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容