HTTP協(xié)議作為前端開發(fā)的重要基礎知識,卻是很多非計算機專業(yè)出身的碼農(nóng)的軟肋。筆者通過《圖解http》一書系統(tǒng)的學習了HTTP協(xié)議的基礎內(nèi)容,并旁征博引,試圖用更加簡練的語言著重描述出HTTP協(xié)議需要掌握的重點內(nèi)容,幫助不愛看書的同學節(jié)省時間。
小綱老師
HTTP協(xié)議簡介
《圖解HTTP》一文中這樣描述HTTP在網(wǎng)絡中的地位:
Web使用一種名為HTTP(HyperText Transfer Protocol,超文本傳輸協(xié)議)的協(xié)議作為規(guī)范,完成從客戶端到服務器等一系列運作流程。而協(xié)議是指規(guī)則的約定??梢哉f,Web是建立在HTTP協(xié)議上通信的。
HTTP協(xié)議定義Web客戶端如何從Web服務器請求Web頁面,以及服務器如何把Web頁面?zhèn)魉徒o客戶端。HTTP協(xié)議采用了請求/響應模型??蛻舳讼蚍掌靼l(fā)送一個請求報文,請求報文包含請求的方法、URL、協(xié)議版本、請求頭部和請求數(shù)據(jù)。服務器以一個狀態(tài)行作為響應,響應的內(nèi)容包括協(xié)議的版本、成功或者錯誤代碼、服務器信息、響應頭部和響應數(shù)據(jù)。
HTTP是不保存狀態(tài)的協(xié)議,既無狀態(tài)協(xié)議,協(xié)議本身對于請求或響應之間的通信狀態(tài)不進行保存,因此連接雙方不能知曉對方當前的身份和狀態(tài)。這也是Cookie技術產(chǎn)生的重要原因之一:客戶端的狀態(tài)管理。瀏覽器會根據(jù)從服務器端發(fā)送的響應報文內(nèi) Set-Cookie 首部字段信息自動保持 Cookie。而每次客戶端發(fā)送 HTTP 請求,都會在請求報文中攜帶 Cookie,作為服務端識別客戶端身份狀態(tài)的標識。
TCP/IP 協(xié)議族
為了更好的了解HTTP協(xié)議,我們必須先了解一下 TCP/IP 協(xié)議族。TCP/IP 協(xié)議族是Internet最基本的協(xié)議,HTTP協(xié)議是它的一個子集。TCP/IP協(xié)議族按層次分為以下四層(網(wǎng)絡基礎,最好記?。?/p>
- 應用層
應用層規(guī)定了向用戶提供應用服務時通信的協(xié)議,如:
TCP/IP 協(xié)議族內(nèi)預存了各類通用的應用服務協(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ǎng)絡連接中兩臺計算機之間的數(shù)據(jù)傳輸所使用的協(xié)議。
在傳輸層有兩個性質(zhì)不同的協(xié)議:TCP(Transmission Control Protocol,傳輸控制協(xié)議)和UDP(User Data Protocol,用戶數(shù)據(jù)報協(xié)議)。
TCP協(xié)議是全雙工的,即發(fā)送數(shù)據(jù)和接收數(shù)據(jù)是同步進行的,就好像我們打電話一樣,說話的同時也能聽見。TCP協(xié)議在建立和斷開連接時有三次握手和四次揮手,因此在傳輸?shù)倪^程中更穩(wěn)定可靠但同時就沒UDP那么高效了。
UDP協(xié)議是面向無連接的,也就是說在正式傳遞數(shù)據(jù)之前不需要先建立連接。UDP 協(xié)議不保證有序且不丟失的傳遞到對端,也就是說不夠穩(wěn)定,但也正因如此,UDP協(xié)議比TCP更加高效和輕便。
- 網(wǎng)絡層
網(wǎng)絡層規(guī)定了數(shù)據(jù)通過怎樣的傳輸路線到達對方計算機傳送給對方(IP協(xié)議等)。
與對方計算機之間通過多臺計算機或網(wǎng)絡設備進行傳輸時,網(wǎng)絡層所起的所用就是在眾多的選項內(nèi)選擇一條傳輸路線。就跟攜程提供的回家路線圖作用一樣。
- 鏈路層
用來處理連接網(wǎng)絡的硬件部分,包括控制操作系統(tǒng)、硬件的設備驅(qū)動、NIC(Network Interface Card,網(wǎng)絡適配器,即網(wǎng)卡),及光纖等物理可見部分(還包括連接器等一切傳輸媒介)。硬件上的范疇均在鏈路層的作用范圍之內(nèi)。
一般的web應用的通信傳輸流是這樣的:
發(fā)送端在層與層之間傳輸數(shù)據(jù)時,每經(jīng)過一層時會被打上一個該層所屬的首部信息。反之,接收端在層與層之間傳輸數(shù)據(jù)時,每經(jīng)過一層時會把對應的首部信息去除。
串行連接、持久連接、管道化持久連接、http/2.0多路復用簡介
- 串行連接: HTTP有無連接的特性,即每次連接只能處理一個請求,收到響應后立即斷開連接。HTTP/1.0 版本(稱為串行連接或短連接、短輪詢)中每次HTTP通信后都要斷開TCP連接,所以每個新的HTTP請求都需要建立一個新的連接。但在現(xiàn)在網(wǎng)站動則幾十條HTTP請求的情況下,很容易達到瀏覽器請求上限,并且每次請求都建立新的tcp連接(每次都有三次握手四次揮別)極大的增加了通信開銷。
- 持久連接: 為解決這個問題,有人提出了持久連接(也叫長連接、長輪詢)。一定時間內(nèi),同一域名下的HTTP請求,只要兩端都沒有提出斷開連接,則持久保持TCP連接狀態(tài),其他請求可以復用這個連接通道。HTTP/1.1 實現(xiàn)并默認了所有連接都是持久連接,這樣客戶端發(fā)起多個HTTP請求時就減少了TCP握手造成的網(wǎng)絡資源和通信時間的浪費。但是持久連接采用阻塞模式,下次請求必須等到上次響應返回后才能發(fā)起,如果上次的請求還沒返回響應內(nèi)容,下次請求就只能等著(就是常說的線頭阻塞)。
- 管道化持久連接: 管道化則可以不用等待響應返回而發(fā)送下個請求并按順序返回響應,現(xiàn)代瀏覽器并未默認開啟管道化。(這方面收集到的資料有限不多說了)
- HTTP/2.0多路復用: 每個HTTP請求都有一個序列標識符,這樣瀏覽器可以并發(fā)多個請求,服務器接收到數(shù)據(jù)后,再根據(jù)序列標識符重新排序成不同的請求報文,而不會導致數(shù)據(jù)錯亂( 細節(jié)參照此文)。同樣,服務端也可以并發(fā)返回多個響應給瀏覽器,瀏覽器收到后根據(jù)序列標識重新排序并歸入各自的請求的響應報文。并且同一個域名下的所有請求都復用同一個TCP連接,極大增加了服務器處理并發(fā)的上限。
- WebSocket: WebSocket是HTML5提出的一種客戶端和服務端通訊的全雙工協(xié)議,由客戶端發(fā)起請求,建立連接之后不僅客戶端可以主動向服務端發(fā)送請求,服務端可以主動向客戶端推送信息。
看圖區(qū)分三種鏈接:
如圖中(a):串行連接每次發(fā)起請求都必須建立新的tcp連接。
如圖中(b):持久連接多個http請求可以復用同一個tcp連接,但是下次請求必須在上次響應返回之后進行。
如圖中(c):管道化持久連接也可以復用同一個tcp連接,并且可以不用等待發(fā)出多個http請求,但是響應必須按順序返回。
URI
HTTP協(xié)議使用 URI 定位互聯(lián)網(wǎng)上的資源。概念:
- URI(Universal Resource Identifier:統(tǒng)一資源標識符)
- URL(Universal Resource Locator:統(tǒng)一資源定位符)
- URN(Universal Resource Name:統(tǒng)一資源名稱)。
個人理解URI是一個資源文件的不同表示方法的總稱。比如一個文件 a.html ,既可以用這個文件的名字 a.html 來表示,也可以用文件路徑 www.baidu.com/a.html 來表示,甚至可以用 urn:a:1535-3613 這樣的標識符來表示。他們的關系如下:
HTTP版本
對于HTTP版本更詳細的區(qū)別,筆者不才,請參考這篇文章
HTTP/1.0
最早的http只是使用在一些較為簡單的網(wǎng)頁上和網(wǎng)絡請求上,所以比較簡單,每次請求都打開一個新的TCP鏈接,收到響應之后立即斷開連接。
HTTP/1.1
- HTTP/1.1 引入了更多的緩存控制策略,如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等
- HTTP/1.1 允許范圍請求,即在請求頭中加入
Range頭部 - HTTP/1.1 的請求消息和響應消息都必須包含
Host頭部,以區(qū)分同一個物理主機中的不同虛擬主機的域名 - HTTP/1.1 默認開啟持久連接,在一個TCP連接上可以傳送多個HTTP請求和響應,減少了建立和關閉連接的消耗和延遲。
HTTP/2.0
在 HTTP/2 中,有兩個非常重要的概念,分別是幀(frame)和流(stream),理解這兩個概念是理解下面多路復用的前提。 幀代表數(shù)據(jù)傳輸?shù)淖钚〉膯挝?,每個幀都有序列標識表明該幀屬于哪個流,流也就是多個幀組成的數(shù)據(jù)流,每個流表示一個請求。這里有個chrome擴展程序,可以方便的查看當前網(wǎng)站的HTTP請求版本(安裝后在chrome開發(fā)工具-Network-在Name/Size/Time表格頭右鍵選擇Procotol,即可查看協(xié)議版本)。
- 新的二進制格式: HTTP/1.x的解析是基于文本的?;谖谋緟f(xié)議的解析存在天然缺陷,文本的表現(xiàn)形式有多樣性,要做到全面性考慮的場景必然很多。二進制則不同,只識別0和1的組合?;谶@種考慮HTTP/2.0的協(xié)議解析采用二進制格式,方便且強大。
- 多路復用: HTTP/2.0支持多路復用,這是HTTP/1.1持久連接的升級版。多路復用,就是在一個 TCP 連接中可以存在多條流,也就是可以發(fā)送多個請求,服務端則可以通過幀中的標識知道該幀屬于哪個流(即請求),通過重新排序還原請求。多路復用允許并發(fā)的發(fā)起多個請求,每個請求及該請求的響應不需要等待其他的請求或響應,避免了線頭阻塞問題。這樣某個請求任務耗時嚴重,不會影響到其它連接的正常執(zhí)行,極大的提高傳輸性能。
- 頭部壓縮: HTTP/1.x的請求和響應頭部帶有大量信息,而且每次請求都要重復發(fā)送,HTTP/2.0使用encoder來減少需要傳輸?shù)念^部大小,通訊雙方各自cache一份頭部 fields表,既避免了重復頭部的傳輸,又減小了需要傳輸?shù)拇笮 ?/li>
- 服務端推送: 這里的服務端推送指把客戶端所需要的css/js/img資源伴隨著index.html一起發(fā)送到客戶端,省去了客戶端重復請求的步驟(從緩存中?。?。
HTTP/3.0
HTTP/2.0 使用了多路復用,一般來說同一域名下只需要使用一個 TCP 連接。但當這個連接中出現(xiàn)了丟包的情況,那就會導致整個 TCP 都要開始等待重傳,也就導致了后面的所有數(shù)據(jù)都被阻塞了。反而對于 HTTP/1.0 來說,可以開啟多個 TCP 連接,出現(xiàn)丟包反倒只會影響其中一個連接,剩余的 TCP 連接還可以正常傳輸數(shù)據(jù)。 出現(xiàn)包阻塞的原因是因為底層TCP協(xié)議導致的問題,但是修改TCP協(xié)議是不現(xiàn)實的問題,就像typeof null === 'object'一樣,修改這個問題會導致出現(xiàn)更多的問題。既然不能修改你,那就另起一個協(xié)議取代你。Google 基于 UDP 協(xié)議推出了一個的 QUIC 協(xié)議,并且使用在了 HTTP/3 上。
QUIC 基于 UDP,但是UDP本身存在不穩(wěn)定性等諸多問題,所以QUIC在UDP的基礎上新增了很多功能,比如多路復用、0-RTT、使用 TLS1.3 加密、流量控制、有序交付、重傳等等功能。優(yōu)點諸多,參考這里:
- 避免包阻塞: 多個流的數(shù)據(jù)包在TCP連接上傳輸時,若一個流中的數(shù)據(jù)包傳輸出現(xiàn)問題,TCP需要等待該包重傳后,才能繼續(xù)傳輸其它流的數(shù)據(jù)包。但在基于UDP的QUIC協(xié)議中,不同的流之間的數(shù)據(jù)傳輸真正實現(xiàn)了相互獨立互不干擾,某個流的數(shù)據(jù)包在出問題需要重傳時,并不會對其他流的數(shù)據(jù)包傳輸產(chǎn)生影響。
- 快速重啟會話: 普通基于tcp的連接,是基于兩端的ip和端口和協(xié)議來建立的。在網(wǎng)絡切換場景,例如手機端切換了無線網(wǎng),使用4G網(wǎng)絡,會改變本身的ip,這就導致tcp連接必須重新創(chuàng)建。而QUIC協(xié)議使用特有的UUID來標記每一次連接,在網(wǎng)絡環(huán)境發(fā)生變化的時候,只要UUID不變,就能不需要握手,繼續(xù)傳輸數(shù)據(jù)。
HTTP報文
用于HTTP協(xié)議交互的信息被稱為HTTP報文??蛻舳说腍TTP報文叫請求報文,服務端的HTTP報文叫響應報文。
請求報文 是由請求行(請求方法、協(xié)議版本)、請求首部(請求URI、客戶端信息等)和內(nèi)容實體(用戶信息和資源信息等,可為空)構成。
響應報文 是由狀態(tài)行(協(xié)議版本、狀態(tài)碼)、響應首部(服務器名稱、資源標識等)和內(nèi)容實體(服務端返回的資源信息)構成。
請求方法
- GET:get方法一般用于獲取服務器資源
- POST:post方法一般用于傳輸實體主體
- PUT:put方法一般用于傳輸文件
- DELETE:delete方法用于刪除文件
- HEAD:head方法用于獲取報文首部,不返回報文主體
- OPTIONS:options方法用于詢問請求URI資源支持的方法
概念很簡單很精辟,還不太理解應用場景的自行百度~~
狀態(tài)碼
HTTP狀態(tài)碼表示客戶端HTTP請求的返回結果、標識服務器處理是否正常、表明請求出現(xiàn)的錯誤等。

首部字段
下面是請求首部和響應首部中的字段名稱和作用:




首部內(nèi)容較多,重點記憶瀏覽器常用的一些字段就行了:

兩種請求
瀏覽器發(fā)送 CORS 請求(跨域請求)時, 會將請求分為簡單請求與復雜請求.
在我們?nèi)粘9ぷ髦? 常用的簡單請求可以將其歸為以下幾點:
1.請求的方法只能為HEAD、GET、POST
2.無自定義請求頭
3.Content-Type只能是這幾種:
text/plain、multipart/form-data、application/x-www-form-urlencoded
復雜請求:
1.PUT, Delete 方法的 ajax 請求
2.發(fā)送 JSON 格式的 ajax 請求(比如post數(shù)據(jù))
3.帶自定義頭的 ajax 請求
如果是簡單請求, 則會先執(zhí)行, 后判斷。執(zhí)行的過程大致如下:
瀏覽器檢測到請求是 CORS 請求, 添加一個origin字段(其中包含頁面源信息: 協(xié)議、域名、端口) ====> 服務端收到后作相應的處理(對比origin, 服務端判斷這個源是否接受)返回結果給瀏覽器 ====> 瀏覽器檢查響應頭是否允許跨域信息 ====> 允許, 那就當做沒事發(fā)生。 不允許, 瀏覽器拋出相應的錯誤信息。
復雜請求在發(fā)生請求時, 如果是 CORS 請求,瀏覽器預先發(fā)送一個 option 請求。瀏覽器這種行為被稱之為預檢請求(注意如果不是跨域請求就不會發(fā)生預檢請求,比如反向代理)。
WEB服務器
這里不關心服務器是Apache還是Nginx,而是在于服務器的作用。一臺服務器可以作為源服務器,也可以作為中轉服務器,甚至可以在一臺服務器上搭建多個不同域名的網(wǎng)站。
虛擬主機
HTTP/1.1規(guī)范允許一臺HTTP服務器搭建多個Web站點。利用虛擬主機的功能,可以在一臺物理服務器(一個IP地址)上虛擬出多個主機,每個主機映射一個獨立的域名。因此,當用戶訪問域名http://www.laogeng.com/時,DNS域名系統(tǒng)會將其解析成IP地址,根據(jù)IP找到物理服務器,然后再通過請求首部的HOST字段(現(xiàn)在知道HOST為什么是HTTP/1.1強制要求攜帶的了吧)確認對應的虛擬主機。
代理服務器
代理服務器就是客戶端和服務端之間的“中間商”,即HTTP請求通過代理服務器轉發(fā)給服務器,再將服務器的響應返回給客戶端的行為。代理服務器可以用來作為緩存服務器,也可以用來隱藏用戶身份(正向代理)或者服務器身份(反向代理)增加安全性。
所謂正向代理,是從客戶/客戶端角度出發(fā),為了從源服務器中取得內(nèi)容,由客戶端向代理服務器發(fā)出請求,并指定目標訪問服務器,然后,代理服務器向源服務器轉交需求,并將獲得的內(nèi)容返回給客戶端。需要注意的是,在正向代理過程中隱藏了真是請求的客戶端,即服務端不知道正式請求客戶是誰。(科學上網(wǎng))
所謂反向代理,是從客戶端發(fā)向反向代理出請求,反向代理服務器收到需求后判斷請求走向何處,然后再將結果反饋給客戶端。同樣需要注意的是,在反向代理過程中,隱藏了內(nèi)部服務器的信息,用戶不需要知道是具體哪一臺服務器提供的服務,只要知道反向代理服務器是誰就好了,我們甚至可以把反向代理服務器當做真正服務器看待。這種形式的代理通常被用作實現(xiàn)負載均衡,比如Nginx就是一種出色的反向代理服務器。
-
反向代理解決跨域問題:我們前端在使用 vue-cli 這種腳手架工具進行開發(fā)時,經(jīng)常會遇到跨域的問題,因為項目自身啟動本地服務是需要占用一個端口(如 http://localhost:8080)的,所以必然會產(chǎn)生跨域的問題(因為本地服務端口和服務端接口地址不是同源)。在使用webpack做構建工具的項目中,經(jīng)常會使用proxyTable代理實現(xiàn)跨域(具體實現(xiàn)自行百度)。之所以出現(xiàn)跨域是因為瀏覽器有同源策略的限制,但服務器是沒有的同源策略的限制的。當我們本地服務(假設域名:http://localhost:8080)要請求目標服務器(假設域名:http://target.com)的資源的時候,我們不直接請求 target.com,而是請求本地服務自身 http://localhost:8080(這時是同源請求,不存在跨域),本地代理服務再將接口轉發(fā)給 target.com(注意這時候是兩個服務器直接的通信了,而不是客戶端和服務器的通信,所以更不存在跨域),本地服務獲取到目標服務器的響應數(shù)據(jù)之后通過再代理偽裝成本地服務請求的返回值返回給客戶端。
本地服務在瀏覽器向本地服務發(fā)起請求 --> 本地代理轉發(fā) --> 目標服務器 --> 響應數(shù)據(jù)后通過代理偽裝成本地服務器請求的返回值 --> 瀏覽器接受到目標服務器的數(shù)據(jù)
vue-cli反向代理配置如下:
//vue.config.js
......
devServer: {
port: 8080, // 配置端口
open: true, // 項目啟動自動開啟瀏覽器
compress: true, // 開啟壓縮
overlay: { // 設置讓瀏覽器 overlay 同時顯示警告和錯誤
warnings: true,
errors: true
},
// 設置請求反向代理
proxy: {
'/api': { // 要代理的接口的匹配字符
target: process.env.BASE_URL, // 接口域名
secure: false,
changeOrigin: true
}
}
},
......
需要注意如果要用反向代理,則在 axios 配置的時候,請求baseURL必須設置為字符串'/',否則 proxy 會匹配不到'/api'導致代理失敗。
緩存服務器
緩存服務器指的是將需要頻繁訪問的網(wǎng)絡內(nèi)容存放在離用戶較近、訪問速度更快的服務器中,以提高內(nèi)容訪問速度的一種技術。緩存服務器是瀏覽器和源服務器之間的中間服務器,瀏覽器先向這個中間服務器發(fā)起HTTP請求,經(jīng)過處理后(比如權限驗證,緩存匹配等),再將請求轉發(fā)到源服務器。
HTTPS
HTTP本身沒有任何保密性,所以HTTP傳輸?shù)臄?shù)據(jù)相當于都是在網(wǎng)上在以明文的方式裸奔。為了解決這個問題,出現(xiàn)了各種加密技術:
對稱加密:唯一密鑰
key1可用來加密也可用來解密。這樣的加密需要雙方都擁有密鑰key1,如果第一次傳輸密鑰被第三方截獲就玩完。非對稱加密:公鑰
key3和私鑰key2都可用于對應的加密和解密,即可用公鑰加密私鑰解密,也可用私鑰加密公鑰解密。服務端會生成一對密鑰,一個私鑰保存在服務端,僅自己知道,另一個是公鑰,公鑰可以自由發(fā)布供任何人使用??蛻舳说拿魑耐ㄟ^公鑰加密后的密文需要用私鑰解密。非對稱密鑰在加密和解密的過程的使用的密鑰是不同的密鑰,加密和解密是不對稱的,所以稱之為非對稱加密。與對稱密鑰加密相比,非對稱加密無需在客戶端和服務端之間共享密鑰,只要私鑰不發(fā)給任何用戶,即使公鑰在網(wǎng)上被截獲,也無法被解密,僅有被竊取的公鑰是沒有任何用處的。混合加密:服務端先用非對稱加密的私鑰
key2加密對稱加密的密鑰key1并傳給客戶端,客戶端用非對稱加密的公鑰key3解密出對稱加密的密鑰key1,雙方都有了密鑰key1,開始利用key1加密通信。缺點:中間人可以自己生成非對稱加密公鑰替換掉服務端公鑰發(fā)送給客戶端,而此時客戶端并無法驗證公鑰的可信性。-
SSL:首先需要從證書認證機構申請證書(證書中含有證書簽名和服務端公鑰
key3)。在客戶端發(fā)起HTTP請求時,服務端將證書發(fā)送給客戶端??蛻舳苏J證證書的真?zhèn)?,然后解密出服務端公鑰key3,用公鑰加密自己生成的對稱加密密鑰key1并傳給服務端,最后利用key1加密進行通話。至于安全性,由于私鑰是機構的,可以避免第三方偽造證書。并且就算得到了服務端公鑰,也無法解密出公鑰key3加密過的對稱加密密鑰key1。
image.png
HTTPS基于HTTP協(xié)議,通過SSL或TLS(可以看作SSL3.0)提供加密處理數(shù)據(jù)、驗證對方身份以及數(shù)據(jù)完整性保護。特點如下: 內(nèi)容加密:采用混合加密技術,中間者無法直接查看明文內(nèi)容
驗證身份:通過證書認證客戶端訪問的是自己的服務器
保護數(shù)據(jù)完整性:防止傳輸?shù)膬?nèi)容被中間人冒充或者篡改
HTTPS和HTTP的區(qū)別主要如下:
- HTTPS協(xié)議需要到CA(證書頒發(fā)機構)申請證書,一般免費證書很少,需要交費。
- HTTP協(xié)議運行在TCP之上,所有傳輸?shù)膬?nèi)容都是明文,HTTPS運行在SSL/TLS之上,SSL/TLS運行在TCP之上,所有傳輸?shù)膬?nèi)容都經(jīng)過加密的。
- HTTP和HTTPS使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
- http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由HTTP+SSL協(xié)議構建的可進行加密傳輸、身份認證的網(wǎng)絡協(xié)議,可以有效的防止運營商劫持,解決了防劫持的一個大問題,比http協(xié)議安全。
WEB安全防范
XSS 攻擊
XSS 攻擊全稱跨站腳本攻擊,是利用html可以執(zhí)行<script>alert(1)</script>的特性,想盡辦法將腳本注入頁面中的攻擊手段。XSS攻擊有兩種,一種是通過修改瀏覽器URL導致腳本被注入到頁面,另一種是通過輸入框?qū)⒛_本代碼注入數(shù)據(jù)庫。前面一種會被chrome瀏覽器自動防御攻擊(但最好還是手動也防御一下),后面一種則需要我們手動防御,推薦使用'xss'庫的白名單過濾防御方法:
const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1><script>alert("xss");</script>
CSRF 攻擊
CSRF中文名為跨站請求偽造。假如掘金有個加關注的GET接口,id參數(shù)是關注人Id,如下:
https://juejin.im?id=5cd0438c6fb9a031ec6d3ab2
那我只需要在我的一個頁面里面寫一個img標簽:
<img src="https://juejin.im?id=5cd0438c6fb9a031ec6d3ab2" />
那么只要有已經(jīng)登錄掘金的用戶打開我這個頁面,就會自動關注我。 就算是改為POST請求,也可以通過在頁面使用form表單提交的方式自動關注。 CSRF攻擊是源于Web的隱式身份驗證機制!Web的身份驗證機制雖然可以保證一個請求是來自于某個用戶的瀏覽器,但卻無法保證該請求是用戶批準發(fā)送的。CSRF攻擊的問題一般是由服務端解決,防范 CSRF 攻擊可以遵循以下幾種規(guī)則:
- Get 請求不用于對數(shù)據(jù)進行修改
- Cookie設置
HTTP Only - 接口設置禁止跨域
- 請求時附帶驗證信息,比如驗證碼或者 Token
點擊劫持
點擊劫持是一種視覺欺騙的攻擊手段。攻擊者將需要攻擊的網(wǎng)站通過 iframe 嵌入自己的網(wǎng)頁中,并將 iframe 設置為透明,然后誘使用戶在該頁面上進行操作,此時用戶將在不知情的情況下點擊透明的iframe頁面(偸yck大佬一張圖會不會被抓┭┮﹏┭┮):

防御方法:
還是讓后端大佬解決,使用一個HTTP響應頭——X-Frame-Options。X-Frame-Options可以說是為了解決點擊劫持而生的,它有三個可選的值:
- DENY:瀏覽器會拒絕當前頁面加載任何frame頁面;
- SAMEORIGIN:frame頁面的地址只能為同源域名下的頁面;
- ALLOW-FROM origin:允許frame加載的頁面地址;
中間人攻擊
中間人攻擊是攻擊方同時與服務端和客戶端建立起了連接,并讓對方認為連接是安全的,但是實際上整個通信過程都被攻擊者控制了。攻擊者不僅能獲得雙方的通信信息,還能修改通信信息。中間人攻擊的本質(zhì)是客戶端和服務端之間的認證和信任問題。
對稱加密、非對稱加密、混合加密技術都沒有有效防止中間人攻擊,因為中間人可以截取首次傳輸?shù)拿荑€并偷天換日,而客戶端或服務端并無法得知。HTTPS作為防止中間人攻擊的終極手段,引入證書機制解決了客戶端和服務端的信任問題,從而較為有效的防止了中間人攻擊。
小結
以上就是前端需要掌握的HTTP相關知識點,能力所限部分知識點講述可能不甚清晰,還請看官們有不清楚的地方直接批評改正。
前端是一門龐大的學科,雖然對入門門檻要求不高,但是其知識體系之龐大讓人望洋興嘆。小子作為半路出家的前端小白,打算按照大牛的 指點(感謝) 從頭開始學習前端,每學一個知識點都會作篇總結,加深自己理解并方便他人查閱。
推薦閱讀另一篇有關http協(xié)議的文章HTTP 協(xié)議超級詳解,對 HTTP 的講解更詳細。
