1 Web及網(wǎng)絡(luò)基礎(chǔ)
1.1 使用 HTTP 協(xié)議訪問 Web
Web 使用一種名為 HTTP(HyperText Transfer Protocol叮雳,超文本傳輸協(xié)議)的協(xié)議作為規(guī)范,完成從客戶端到服務(wù)器端等一系列運(yùn)作流程秧均。 而協(xié)議是指規(guī)則的約定哟绊〔诠浚可以說号枕,Web 是建立在 HTTP 協(xié)議上通信的懂更。
- 超文本:不局限于文本信息锌订,包括文本竹握、圖片、音頻辆飘、視頻等
- 傳輸:客戶端<->服務(wù)器 雙向傳遞
- 協(xié)議:約定好的一套規(guī)則
1997年1月公布的 HTTP/1.1 是目前主流的 HTTP 協(xié)議版本啦辐。
1.2 TCP/IP的分層管理
為了理解 HTTP,我們有必要先了解一下TCP/IP 協(xié)議族蜈项。
通常使用的網(wǎng)絡(luò)(包括互聯(lián)網(wǎng))是在 TCP/IP 協(xié)議族的基礎(chǔ)上運(yùn)作的芹关。而 HTTP 屬于于它內(nèi)部的一個(gè)子集。
TCP/IP 協(xié)議族里重要的一點(diǎn)就是分層紧卒。以下為兩種分層模型侥衬。TCP/IP四層模型以及OSI七層模型。
1.3 TCP/IP通信傳輸流
利用 TCP/IP 協(xié)議族進(jìn)行網(wǎng)絡(luò)通信時(shí),會通過分層順序與對方進(jìn)行通信轴总。發(fā)送端從應(yīng)用層往下走直颅,接收端則向上往應(yīng)用層走。
- 首先作為發(fā)送端的客戶端在應(yīng)用層 (HTTP 協(xié)議)發(fā)出一個(gè)想看某個(gè) Web 頁面的 HTTP 請求怀樟。
- 接著功偿,為了傳輸方便,在傳輸層(TCP 協(xié)議)把從應(yīng)用層接收到的數(shù)據(jù)(HTTP請求報(bào)文)進(jìn)行分割往堡,在各個(gè)報(bào)文上打上標(biāo)記序號及端口號后轉(zhuǎn)發(fā)給網(wǎng)絡(luò)層械荷。
- 在網(wǎng)絡(luò)層(IP 協(xié)議),增加作為通信目的地的 MAC 地址后轉(zhuǎn)發(fā)給鏈路層虑灰。
- 接收端的服務(wù)器在鏈路層接收到數(shù)據(jù)吨瞎,按順序往上層發(fā)送,當(dāng)傳輸?shù)綉?yīng)用層瘩缆,才能算真正接收到由客戶端發(fā)送過來的 HTTP 請求关拒。
1.4 與 HTTP關(guān)系密切的協(xié)議:IP、TCP庸娱、DNS
1.4.1 負(fù)責(zé)域名解析的DNS服務(wù)
DNS(Domain Name System)服務(wù)是和 HTTP 協(xié)議一樣位于應(yīng)用層的協(xié)議。它提供 域名<--->IP 地址 之間的解析服務(wù)熟尉。
IP和域名之間是多對多的映射關(guān)系
- 一個(gè)域名可以指向多個(gè)ip归露,用來做負(fù)載均衡(DNS服務(wù)商根據(jù)你的位置和運(yùn)營商返回不同的解析結(jié)果,參見CDN的應(yīng)用)
可以在終端ping www.baidu.com
通過ping得到一個(gè)域名對應(yīng)的IP斤儿,baidu的IP有很多剧包,所以ping www.baidu.com
可以得到不同的IP,一個(gè)域名對應(yīng)的IP是由域名的所有者指定的往果。
更改 hosts可以手動(dòng)指定域名對應(yīng)的IP疆液。mac中打開終端,sudo vim /etc/hosts
就可以手動(dòng)指定域名對應(yīng)的IP陕贮,我們將www.baidu.com的IP指定為本機(jī)地址堕油。
再次在終端ping www.baidu.com
試試,發(fā)現(xiàn)IP地址變成本機(jī)地址了肮之。瀏覽器如果還是能訪問百度的話掉缺,是因?yàn)闉g覽器有DNS緩存,換一個(gè)瀏覽器就好戈擒。試驗(yàn)完還是改回來把眶明,不然訪問不了百度了。
- 同樣一個(gè)ip可以被多個(gè)域名指向筐高,例如大家所購買的虛擬主機(jī)搜囱。
1.4.2 確背笄疲可靠性的 TCP 協(xié)議
握手過程中使用了SYN (synchronize同步標(biāo)志)和 ACK(acknowledgement確認(rèn)標(biāo)志)。
1.4.3 負(fù)責(zé)傳輸?shù)?IP 協(xié)議
IP 協(xié)議的作用是把各種數(shù)據(jù)包傳送給對方犬辰,IP 間的通信依賴 MAC 地址嗦篱。我們使用IP層上的ARP協(xié)議,根據(jù)通信方的 IP 地址反查出對應(yīng)的MAC地址幌缝。
IP 地址指明了節(jié)點(diǎn)被分配到的地址灸促,MAC 地址是指網(wǎng)卡所屬的固定地址。IP 地址可以和 MAC 地址進(jìn)行配對涵卵。IP 地址可變浴栽,但 MAC 地址基本上不會更改。
無論哪臺計(jì)算機(jī)或網(wǎng)絡(luò)設(shè)備都無法全面掌握互聯(lián)網(wǎng)中的細(xì)節(jié)轿偎。在到達(dá)通信目標(biāo)前的中轉(zhuǎn)過程中典鸡,計(jì)算機(jī)或路由器等網(wǎng)絡(luò)設(shè)備只能獲悉粗略的傳輸路線。而在進(jìn)行中轉(zhuǎn)時(shí)坏晦,會利用下一站中轉(zhuǎn)設(shè)備的 MAC 地址來搜索下一個(gè)中轉(zhuǎn)目標(biāo)萝玷。
1.5 URI和URL
URI (Uniform Resource Identifier 統(tǒng)一資源標(biāo)識符)
- Uniform 統(tǒng)一:規(guī)定統(tǒng)一的格式,如http: 或 ftp:
- Resource資源 :可標(biāo)識的任何東西
- Identifier標(biāo)識符:表示可標(biāo)識的對象
URI由兩個(gè)主要的子集構(gòu)成
- URL:通過描述資源的位置來描述資源
- URN:通過名字來識別資源昆婿,和位置無關(guān)
端口是什么
- TCP或UDP協(xié)議的規(guī)則球碉,一個(gè)端口對應(yīng)一個(gè)服務(wù),用端口區(qū)分不同的服務(wù)
- 0到1023號端口是保留端口(1024~65535的端口都可以使用)仓蛆,請背誦以下常用端口
- 21端口 ----FTP
- 80端口 ----HTTP
- 53端口 ----DNS
- 443端口 ----HTTPS
- 1080端口 ----SOCKS代理(翻墻時(shí)默認(rèn)用1080端口)
2 簡單的HTTP協(xié)議
2.1 請求和響應(yīng)
請求必定由客戶端(瀏覽器)發(fā)出睁冬,而服務(wù)器端回復(fù)響應(yīng)。
2.1.1 服務(wù)器(Server)由兩部分組成
- 硬件(一個(gè)cpu很牛內(nèi)存很強(qiáng)的沒有顯示器的電腦)例如cpu128核 內(nèi)存32g
- 軟件(程序)例如阿里云服務(wù)器
2.1.2如何用命令行訪問一個(gè)網(wǎng)頁 / 如何得到響應(yīng)
$ curl -L http://www.baidu.com
2.1.3 請求和響應(yīng)報(bào)文的構(gòu)成
請求報(bào)文由四部分構(gòu)成:
1 請求行 (第一行)方法 路徑 協(xié)議/版本號 例如 GET/ndex.html HTTP/1.1
2 請求首部 (n行) KEY1: VALUE1 形式
3 空行 (1行回車,用于表示第二部分結(jié)束能庆,如果沒有回車怎么知道第二部分over了)
4 消息體 (n行)內(nèi)容隨便施禾,格式可在第二部分指定,當(dāng)然也可以不指定搁胆,注意query string不是消息體 只是把請求行里的內(nèi)容拿出來而已 GET方法約定俗成沒有請求體
請求報(bào)文中的第二部分 2HTTP首部字段可細(xì)分以下三部分
- 請求首部字段
- 通用首部字段
- 實(shí)體首部字段
關(guān)于請求報(bào)文中的第四部分 4消息體(請求實(shí)體):
請求主體的內(nèi)容由傳輸者定義弥搞,傳遞了客戶端到服務(wù)器的內(nèi)容,其格式可以任意指定丰涉。譬如實(shí)體中可以放參數(shù)的序列化形式( a = 1 & b = 2 這種),或者直接放表單對象( Form Data對象斯碌,上傳時(shí)可以夾雜參數(shù)以及?件)一死,等等。
響應(yīng)報(bào)文由四部分構(gòu)成:
1 狀態(tài)行 (第一行) 協(xié)議/版本號 狀態(tài)碼 狀態(tài)描述 例如 HTTP/1.1 200 OK
2 請求首部 (n行) KEY1: VALUE1 形式
3 空行 (1行回車)
4 消息體 (n行)Chrome會把第四部分內(nèi)容放在response中顯示
請求報(bào)文中的第二部分 2HTTP首部字段可細(xì)分以下三部分
- 響應(yīng)首部字段
- 通用首部字段
- 實(shí)體首部字段
關(guān)于響應(yīng)報(bào)文中的第四部分 4消息體(響應(yīng)實(shí)體):
響應(yīng)實(shí)體(主體)中傻唾,就是放服務(wù)端需要傳給客戶端的內(nèi)容投慈。?般現(xiàn)在的接口請求時(shí)承耿,實(shí)體中就是對于的信息的json格式,?像?面請求這種伪煤,?面就是直接放了一個(gè)html字符串加袋,然后瀏覽器??己解析并渲染。
2.1.4 HTTP/1.1首部字段一覽
HTTP首部規(guī)定了一個(gè)請求的約束和規(guī)則抱既,以鍵值對的形式呈現(xiàn)职烧。
HTTP 首部字段結(jié)構(gòu)
首部字名: 字段值
HTTP 首部字段根據(jù)實(shí)際用途被分為以下 4 種類型。
- 通用首部字段:請求報(bào)文和響應(yīng)報(bào)文兩方都會使用的首部防泵。
- 請求首部字段 :從客戶端向服務(wù)器端發(fā)送請求報(bào)文時(shí)使用的首部蚀之。補(bǔ)充了請求的附加內(nèi)容、客戶端信息捷泞、響應(yīng)內(nèi)容相關(guān)優(yōu)先級等信息足删。
- 響應(yīng)首部字段:從服務(wù)器端向客戶端返回響應(yīng)報(bào)文時(shí)使用的首部。補(bǔ)充了響應(yīng)的附加內(nèi)容锁右,也會要求客戶端額外的內(nèi)容信息失受。
- 實(shí)體首部字段:針對請求報(bào)文和響應(yīng)報(bào)文的實(shí)體部分使用的首部。補(bǔ)充了資源內(nèi)容更新時(shí)間等與實(shí)體有關(guān)的信息咏瑟。
下圖各個(gè)參數(shù)是什么意思
2.2 HTTP方法
方法 | 描述 |
---|---|
GET | 從服務(wù)器獲取資源拂到,獲取時(shí)提供的是參數(shù)(queryString) |
POST | 向服務(wù)器提交數(shù)據(jù),傳遞表單資源就是POST响蕴。 |
HEAD | 獲得報(bào)文首部谆焊。與 GET 相同,但只返回 HTTP 報(bào)頭浦夷,不返回文檔主體辖试,用于確認(rèn)URI的有效性及資源更新的日期時(shí)間等。 |
PUT | 往服務(wù)器上傳資源劈狐。鑒于 HTTP/1.1 的 PUT 方法自身不帶驗(yàn)證機(jī)制罐孝,任何人都可以上傳文件,存在安全性問題肥缔,一般web網(wǎng)站不使用此方法莲兢,若配合web的安全驗(yàn)證機(jī)制,或者架構(gòu)采用REST標(biāo)準(zhǔn)的網(wǎng)站续膳,就可能開放使用此方法改艇。 |
DELETE | 刪除指定資源,是與PUT相反的方法坟岔。出于安全考慮谒兄,一般web網(wǎng)站不使用此方法,若配合web的安全驗(yàn)證機(jī)制社付,或者架構(gòu)采用REST標(biāo)準(zhǔn)的網(wǎng)站承疲,就可能開放使用此方法邻耕。 |
OPTIONS | 詢問服務(wù)器支持的 HTTP 方法。 |
CONNECT | 要求采用隧道協(xié)議連接代理燕鸽。該方法要求在于代理服務(wù)器通信時(shí)建立隧道兄世,實(shí)現(xiàn)用隧道協(xié)議進(jìn)行TCP通信,主要使用SSL(安全套接層)和TLS(傳輸層安全)協(xié)議把通信內(nèi)容加密后經(jīng)過網(wǎng)絡(luò)傳輸啊研。 |
TRACE: | 追蹤路徑御滩。讓web服務(wù)器端將之前的請求通信環(huán)回給客戶端的方法。發(fā)送請求時(shí)悲伶,在Max-Frowards首部字段中填入數(shù)值艾恼,每經(jīng)過一個(gè)服務(wù)器端就-1,當(dāng)數(shù)值為0時(shí)麸锉,停止傳輸钠绍,最后收到服務(wù)器返回狀態(tài)碼200 OK的響應(yīng)。該方法很容易引起XST(跨站追蹤)攻擊花沉,很少用到柳爽。 |
2.2.1 GET和POST的區(qū)別
GET用于從服務(wù)器端獲取數(shù)據(jù),包括靜態(tài)資源(HTML|JS|CSS|Image等等)碱屁、動(dòng)態(tài)數(shù)據(jù)展示(列表數(shù)據(jù)磷脯、詳情數(shù)據(jù)等等)。
POST用于向服務(wù)器提交(更新)數(shù)據(jù)娩脾,比如增刪改數(shù)據(jù)赵誓,提交一個(gè)表單新建一個(gè)用戶、或修改一個(gè)用戶等柿赊。
你能用GET進(jìn)行更新操作俩功,也能用POST進(jìn)行查詢操作 ,但是那不是這倆Method的本意碰声。前者是獲取诡蜓、 后者是更新。獲取時(shí)提供的是參數(shù)(queryString) 更新則是表單 胰挑。
冪等的概念是指同一個(gè)請求方法執(zhí)行多次和僅執(zhí)行一次的效果完全相同蔓罚。
比較方面 | GET | POST |
---|---|---|
后退按鈕/刷新(冪等性) | 無害(冪等) | 數(shù)據(jù)會被重新提交(瀏覽器應(yīng)該告知用戶數(shù)據(jù)會被重新提交,POST語義不是冪等的瞻颂,重復(fù)請求可能會帶來意想不到的后果豺谈。) |
書簽 | 可收藏為書簽 | 不可收藏為書簽 |
緩存 | 能被緩存 | 不能緩存 |
歷史 | 參數(shù)保留在瀏覽器歷史中 | 參數(shù)不會保存在瀏覽器歷史中。 |
對數(shù)據(jù)長度的限制 | GET傳遞的參數(shù)只能帶URL后面贡这,文本格式QueryString茬末,各瀏覽器一般有長度限制(URL 的最大長度是 2048 個(gè)字符)。 | 無限制藕坯。 |
對數(shù)據(jù)類型的限制 | 只允許 ASCII 字符团南。 | 沒有限制。也允許二進(jìn)制數(shù)據(jù)炼彪。 |
安全性 | 與 POST 相比吐根,GET 的安全性較差,因?yàn)樗l(fā)送的數(shù)據(jù)是 URL 的一部分辐马,可以直接看到拷橘,明文傳輸。GET請求會保存在瀏覽器歷史紀(jì)錄或 web 服務(wù)器日志中喜爷。 | POST是通過header請求冗疮,可以開發(fā)者工具或者抓包可以看到,同樣也是明文的檩帐,請求不會保留在瀏覽器歷史記錄中术幔。 |
是否改變服務(wù)器狀態(tài) | 否,get多少次都不應(yīng)改變頁面呈現(xiàn)的數(shù)據(jù)湃密,而post會 | 是 |
2.3 長連接(持久連接) 與短連接
短連接:http1 . 0 中诅挑,默認(rèn)使?用的是短連接,也就是說泛源,瀏覽器?每進(jìn)?一次http操作拔妥,就建?一次連接,任務(wù)結(jié)束就中斷連接达箍,譬如每一個(gè)靜態(tài)資源請求都是一個(gè)單獨(dú)的連接没龙。
長連接:http1.1起硬纤,默認(rèn)使用?連接,使?長連接會有這?行 Connection:keep-alive碘梢,?個(gè)tcp/ip連接上可以連續(xù)發(fā)送多個(gè)數(shù)據(jù)包咬摇。持久連接的特點(diǎn)是,只要任意一端沒有明確提出斷開連接煞躬,則保持 TCP 連接狀態(tài)肛鹏。
2.4 使用Cookie進(jìn)行用戶識別及狀態(tài)管理
HTTP 是無狀態(tài)協(xié)議,它不對之前發(fā)生過的請求和響應(yīng)的狀態(tài)進(jìn)行處理恩沛。每當(dāng)有新的請求發(fā)送時(shí)在扰,就會有對應(yīng)的新響應(yīng)產(chǎn)生。協(xié)議本身并不保留之前一切的請求或響應(yīng)報(bào)文的信息雷客。由于不必保存狀態(tài)芒珠,自然可減少服務(wù)器的CPU及內(nèi)存資源的消耗,這是為了更快地處理大量事務(wù)搅裙。
HTTP/1.1 雖然是無狀態(tài)協(xié)議皱卓,但為了實(shí)現(xiàn)期望的保持狀態(tài)功能裹芝, 于是引入了 Cookie 技術(shù)。Cookie 技術(shù)通過在請求和響應(yīng)報(bào)文中寫入 Cookie 信息來控制客戶端的狀態(tài)娜汁。cookie是瀏覽器?的一種本地存儲?方式嫂易,用來幫助客戶端和服務(wù)端通信的,常用來進(jìn)?身份校驗(yàn)掐禁,結(jié)合服務(wù)端的session使用怜械。
Cookie 會根據(jù)從服務(wù)器端發(fā)送的響應(yīng)報(bào)文內(nèi)的一個(gè)叫做 Set-Cookie 的首部字段信息,通知客戶端保存 Cookie傅事。當(dāng)下次客戶端再次向該服務(wù)器發(fā)送請求時(shí)缕允,客戶端會自動(dòng)在請求報(bào)文中加入 Cookie 值后發(fā)送出去。
服務(wù)器端發(fā)現(xiàn)客戶端發(fā)送過來的 Cookie 后蹭越,會先檢查是從哪 一個(gè)客戶端發(fā)來的連接請求障本,然后對比服務(wù)器上的記錄,最后得到之前的狀態(tài)信息响鹃。
HTTP 請求報(bào)文和響應(yīng)報(bào)文的內(nèi)容如下彼绷。
下面的表格列舉了 Set-Cookie 的字段值。
Chrome開發(fā)者工具的Applications里面可以看到cookie信息
每個(gè)cookie的信息條目有:Name Value Domain Path Expires Size HTTP 等
2.5 Session管理及Cookie應(yīng)用(用于實(shí)現(xiàn)Session的一種方式)
- 由于HTTP協(xié)議是無狀態(tài)的協(xié)議茴迁,所以服務(wù)端需要記錄用戶的狀態(tài)時(shí)寄悯,就需要用某種機(jī)制來識具體的用戶,這個(gè)機(jī)制就是Session堕义。Session被保存在服務(wù)端的內(nèi)存猜旬、數(shù)據(jù)庫、文件中倦卖,有一個(gè)唯一標(biāo)識即Session ID洒擦。
- 服務(wù)端如何識別特定的客戶?這個(gè)時(shí)候Cookie就登場了怕膛。在第一次創(chuàng)建Session的時(shí)候熟嫩,服務(wù)端會在首部字段 Set-Cookie 內(nèi)寫入 Session ID(如 PHPSESSID=028a8c...)。以后每次請求把這個(gè)會話ID發(fā)送到服務(wù)器褐捻,我就知道你是誰了掸茅。客戶端接收到從服務(wù)器端發(fā)來的Session ID后柠逞,會將其作為 Cookie 保存在本地昧狮。下次發(fā)送HTTP請求的時(shí)候序无,瀏覽器會自動(dòng)發(fā)送Cookie酥馍,Session ID也隨之發(fā)送到服務(wù)器。服務(wù)器通過配對接收到的Session ID獲取Session內(nèi)容帘饶,識別用戶和其認(rèn)證狀態(tài)。
由此可見撒璧,Session 的運(yùn)行依賴 Session ID透葛,而 Session ID 是存在 Cookie 中的,也就是說卿樱,如果瀏覽器禁用了 Cookie 获洲,同時(shí) Session 也會失效(但可以通過其它方式實(shí)現(xiàn),比如在 URL后面都會被附加上一個(gè)諸如 sid=xxxxx 這樣的參數(shù)殿如,服務(wù)端據(jù)此來識別用戶)。 - Cookie還可以用于其他方便用戶的場景下最爬,設(shè)想你某次登陸過一個(gè)網(wǎng)站涉馁,下次登錄的時(shí)候不想再次輸入賬號了,怎么辦爱致?這個(gè)信息可以寫到Cookie里面烤送,訪問網(wǎng)站的時(shí)候,網(wǎng)站頁面的腳本可以讀取這個(gè)信息糠悯,就自動(dòng)幫你把用戶名給填了帮坚,能夠方便一下用戶。這也是Cookie名稱的由來互艾,給用戶的一點(diǎn)甜頭试和。
2.6 HTTP狀態(tài)碼
當(dāng)客戶端向服務(wù)器端發(fā)送請求時(shí),狀態(tài)碼用于描述請求的處理結(jié)果纫普。
2.6.1 具有代表性的14個(gè)狀態(tài)碼
- 200 OK 請求已正常處理
- 204 No Content 請求處理成功阅悍,但沒有資源可返回。(如果用戶定期刷新頁面昨稼,就可以返回204)
- 206 Partial Content 客戶端進(jìn)行連范圍請求节视,而服務(wù)器成功執(zhí)行連這部分的GET請求,響應(yīng)報(bào)文中包含由Content -Range指定范圍的實(shí)體內(nèi)容假栓。
- 301 Moved Permanently 永久重定向
客戶請求的資源已被分配了新的 URI寻行,瀏覽器應(yīng)該自動(dòng)地訪問新的URL。如果已經(jīng)把資源對應(yīng)的 URI 保存為書簽了匾荆,這時(shí)應(yīng)該按 Location 首部字段提示的 URI 重新保存拌蜘。 - 302 Found(Moved Temporatily )臨時(shí)重定向
客戶請求的資源已被分配了新的 URI,希望瀏覽器本次使用新的URI訪問牙丽。302 狀態(tài)碼代表的資源不是被永久移動(dòng)拦坠,只是臨時(shí)性質(zhì)的。如果已經(jīng)把資源對應(yīng)的 URI 保存為書簽了剩岳,不會像301狀態(tài)碼出現(xiàn)時(shí)那樣去更新書簽贞滨。 - 303 See Other 和 302 Found類似,臨時(shí)按新的URI訪問,但303明確表示客戶端應(yīng)當(dāng)使用 GET 方法獲取資源晓铆,這點(diǎn)與302不同勺良。
- 304 Not Modified 協(xié)商緩存返回304狀態(tài)碼,服務(wù)器告訴客戶端:原來緩存的文檔還可以繼續(xù)使用骄噪。如果客戶端發(fā)送了一個(gè)帶條件的GET請求且該請求已被允許尚困,而文檔的內(nèi)容(自上次訪問以來或者根據(jù)請求的條件)并沒有改變,則服務(wù)器應(yīng)當(dāng)返回這個(gè)304狀態(tài)碼链蕊。
- 400 Bad Request 表示請求報(bào)文中存在語法錯(cuò)誤事甜。
- 401 Unauthorized
該狀態(tài)碼表示發(fā)送的請求需要有通過 HTTP 認(rèn)證(BASIC 認(rèn)證、 DIGEST認(rèn)證)的認(rèn)證信息滔韵。另外若之前已進(jìn)行過 1 次請求逻谦,表示用戶認(rèn)證失敗。
- 403 Forbidden
對請求資源的訪問被服務(wù)器拒絕了陪蜻。通常由于服務(wù)器上文件或目錄的權(quán)限設(shè)置導(dǎo)致邦马。 - 404 Not Found
無法找到指定位置的資源。出現(xiàn)這個(gè)錯(cuò)誤的最有可能的原因是服務(wù)器端沒有這個(gè)頁面宴卖。 - 500 Internal Server Error
服務(wù)器端在執(zhí)行請求時(shí)發(fā)生了錯(cuò)誤滋将。一般來說,這個(gè)問題都會在服務(wù)器端的源代碼出現(xiàn)錯(cuò)誤時(shí)出現(xiàn)症昏。 - 503 Service Unavailable
服務(wù)器由于維護(hù)或者負(fù)載過重未能應(yīng)答随闽。這個(gè)狀況是臨時(shí)的,并且將在一段時(shí)間以后恢復(fù)肝谭。例如橱脸,Servlet可能在數(shù)據(jù)庫連接池已滿的情況下返回503。服務(wù)器返回503時(shí)可以提供一個(gè) Retry-After頭分苇。
301 和 302 的區(qū)別是什么添诉?
301 永久重定向,瀏覽器會記住重定向的結(jié)果
302 臨時(shí)重定向 医寿,瀏覽器不會記住的
301 Moved Permanently 客戶請求的文檔在其他地方栏赴,新的URL在Location頭中給出,瀏覽器應(yīng)該自動(dòng)地訪問新的URL靖秩。
302 Found 類似于301须眷,但新的URL應(yīng)該被視為臨時(shí)性的替代,而不是永久性的沟突。注意花颗,在HTTP1.0中對應(yīng)的狀態(tài)信息是“Moved Temporatily”。出現(xiàn)該狀態(tài)代碼時(shí)惠拭,瀏覽器能夠自動(dòng)訪問新的URL扩劝,因此它是一個(gè)很有用的狀態(tài)代碼庸论。注意這個(gè)狀態(tài)代碼有時(shí)候可以和301替換使用。例如棒呛,如果瀏覽器錯(cuò)誤地請求http://host/~user(缺少了后面的斜杠)聂示,有的服務(wù)器 返回301,有的則返回302簇秒。嚴(yán)格地說鱼喉,我們只能假定只有當(dāng)原來的請求是GET時(shí)瀏覽器才會自動(dòng)重定向。請參見307趋观。
3 確保 Web 安全的 HTTPS
3.1 HTTP 的缺點(diǎn)
- 通信使用明文(不加密)扛禽,內(nèi)容可能會被竊聽
- 不驗(yàn)證通信方的身份,因此可能遭遇偽裝
- 無法證明報(bào)文的完整性皱坛,所以可能已遭篡改
3.2 HTTP+加密+認(rèn)證+完整性保護(hù)=HTTPS
HTTPS是身披SSL(Secure Socket Layer)外殼的HTTP编曼,通常HTTP直接和TCP通信,當(dāng)使用SSL時(shí)麸恍,就演變成先和SSL通信,再由 SSL 和 TCP 通信了搀矫。
在采用 SSL 后抹沪,HTTP 就有了 HTTPS 的加密、證書和完整性保護(hù)這些功能瓤球。SSL 是獨(dú)立于 HTTP 的協(xié)議融欧,所以不光是 HTTP 協(xié)議,其他運(yùn)行在 應(yīng)用層的 SMTP 和 Telnet 等協(xié)議均可配和 SSL 協(xié)議使用卦羡≡肓螅可以說 SSL 是當(dāng)今世界上應(yīng)用最為廣泛的網(wǎng)絡(luò)安全技術(shù)。
3.3 HTTPS采用混合加密機(jī)制
HTTPS 采用共享密鑰加密(對稱加密)和公開密鑰加密(非對稱加密)兩者并用的混合加密機(jī)制绿饵。
- 公開密鑰加密相比共享密鑰加密欠肾,其處理速度慢了很多。
- 以共享密鑰加密方式加密時(shí)必須將密鑰也發(fā)給對方拟赊。在互聯(lián)網(wǎng)上轉(zhuǎn)發(fā)密鑰時(shí)刺桃,如果通信被監(jiān)聽那么密鑰就可會落入攻擊者之手,同時(shí)也就失去了加密的意義吸祟。
因此充分利用兩種加密機(jī)制各自優(yōu)勢瑟慈, 在交換密鑰環(huán)節(jié)使用公開密鑰加密方式,之后的建立通信交換報(bào)文階段則使用共享加密方式屋匕。
3.4 證明公開密鑰正確性的證書
公開密鑰加密方式還是存在一些問題的葛碧。那就是無法證明公開密鑰本身就是貨真價(jià)實(shí)的所預(yù)想的那臺服務(wù)器發(fā)行的公開密鑰,或許在公開密鑰傳輸途中过吻,真正的 公開密鑰已經(jīng)被攻擊者替換掉了进泼。
為了證明公開密鑰的正確性,可以使用由數(shù)字證書認(rèn)證機(jī)構(gòu)(CA,Certificate Authority)和其相關(guān)機(jī)關(guān)頒發(fā)的公開密鑰證書缘琅。流程如下:
- 服務(wù)器的運(yùn)營人員向數(shù)字證書認(rèn)證機(jī)構(gòu)提出公開密鑰的申請---->數(shù)字證書認(rèn)證機(jī)構(gòu)在判明申請者的身份后粘都,會用自己的私鑰對服務(wù)器的公開密鑰部署數(shù)字簽名,頒發(fā)公鑰證書(服務(wù)器的公開密鑰+數(shù)字簽名)
- 服務(wù)器將該公鑰證書發(fā)送給客戶端刷袍。
- 客戶端拿到公鑰證書翩隧,使用數(shù)字證書認(rèn)證機(jī)構(gòu)發(fā)布的公鑰(瀏覽器會事先內(nèi)部植入常用認(rèn)證機(jī)關(guān)的公鑰)驗(yàn)證公鑰證書上的數(shù)字簽名,以確認(rèn)服務(wù)器公開密鑰的真實(shí)性呻纹。
3.5 HTTPS 的問題:處理速度慢
SSL 的慢分兩種堆生。
- 通信慢:除去和TCP連接、發(fā)送HTTP請求雷酪、響應(yīng)外淑仆,還需進(jìn)行SSL通信。
- 由于大量消耗 CPU 及內(nèi)存等資源哥力,導(dǎo)致處理速度變慢:SSL在客戶端和服務(wù)器都要進(jìn)行加密解密的運(yùn)算蔗怠,比起HTTP會更多消耗服務(wù)器和客戶端的硬件資源。
因此吩跋,如果是非敏感信息則使用 HTTP 通信寞射,只有在包含個(gè)人信息等敏感數(shù)據(jù)時(shí),采利用 HTTPS 加密通信锌钮。
4 基于 HTTP 的協(xié)議
4.1 HTTP通信的瓶頸
以下這些 HTTP 標(biāo)準(zhǔn)成為了網(wǎng)站性能的瓶頸桥温。
- 一條連接上只可發(fā)送一個(gè)請求
- 請求只能從客戶端開始,客戶端不可以接收除了響應(yīng)以外的指令
- 請求 / 響應(yīng)首部未經(jīng)壓縮就發(fā)送梁丘。首部信息越多延遲越大侵浸。
- 每次互相發(fā)送相同的首部造成的浪費(fèi)較多。
- 可任意選擇數(shù)據(jù)壓縮格式氛谜。非強(qiáng)制壓縮發(fā)送掏觉。
4.2 利用WebSocket實(shí)現(xiàn)瀏覽器和服務(wù)器間的全雙工通信
WebSocket,即 Web 瀏覽器與 Web 服務(wù)器之間全雙工通信標(biāo)準(zhǔn)值漫。一但Web 服務(wù)器與客戶端之間建立起 WebSocket 協(xié)議的通信連接履腋, 之后所有的通信都依靠這個(gè)專用協(xié)議進(jìn)行。通信過程中可互相發(fā)送 JSON惭嚣、XML遵湖、HTML 或圖片等任意格式的數(shù)據(jù)。
WebSocket 協(xié)議的兩個(gè)主要特點(diǎn)晚吞。
- 推送功能:支持由服務(wù)器向客戶端推送數(shù)據(jù)的推送功能延旧。這樣,服務(wù)器可直接發(fā)送數(shù)據(jù)槽地,而不必等待客戶端的請求迁沫。
- 減少通信量:
只要建立起 WebSocket ??接芦瘾,就希望一直保持連接狀態(tài)。和 HTTP 相比集畅,不但每次連接時(shí)的總開銷減少近弟,而且由于 WebSocket 的首部信息很小,通信量也相應(yīng)減少了挺智。
4.2.1WebSocket 通信的實(shí)現(xiàn)
為了實(shí)現(xiàn) WebSocket 通信祷愉,在 HTTP 連接建立之后,需要握手請求和握手響應(yīng)赦颇。
握手請求
使用 HTTP 的 Upgrade 首部字段二鳄, 告知服務(wù)器通信協(xié)議發(fā)生改變,以達(dá)到握手的目的媒怯。
握手響應(yīng)
成功握手確立 WebSocket 連接之后订讼,通信時(shí)不再使用 HTTP 的數(shù)據(jù)幀,而是用 WebSocket 獨(dú)立的數(shù)據(jù)幀扇苞。
4.2.2 WebSocket API
JavaScript 可調(diào)用The WebSocket API欺殿,以 現(xiàn) WebSocket 協(xié)議的全雙工通信。
5 瀏覽器緩存
瀏覽器緩存是瀏覽器在本地磁盤對用戶最近請求過的文檔進(jìn)行存儲脖苏,當(dāng)訪問者再次訪問同一頁面時(shí),瀏覽器就可以直接從本地磁盤加載文檔哄陶。前后端的http交互中帆阳,使?緩存能很大程度上的提升效率哺壶。
5.1強(qiáng)緩存與協(xié)商緩存
緩存可以劃分為強(qiáng)緩存與協(xié)商緩存兩種類型屋吨,區(qū)別如下:
- 強(qiáng)緩存( 200 fromcache)時(shí),瀏覽器如果判斷本地緩存未過期山宾,不用請求服務(wù)器直接使用本地緩存
- 協(xié)商緩存( 304)時(shí)至扰,瀏覽器?會向服務(wù)端發(fā)起http請求,然后服務(wù)端告訴瀏覽?緩存未過期资锰,讓瀏覽?使用本地緩存
對于協(xié)商緩存敢课,使? Ctrl +F5強(qiáng)制刷新可以使得緩存無效。但是對于強(qiáng)緩存绷杜,在未過期時(shí)直秆, 必須更更新資源路路徑才能發(fā)起新的請求(更改了資源路徑相當(dāng)于是請求另一個(gè)資源了)
5.2 通過不同的http頭部區(qū)分強(qiáng)緩存與協(xié)商緩存
5.2.1強(qiáng)緩存
(http1.0) Pragma/Expires
(http1.1) Cache-Control/Cache-Control
- Pragma: no-cache 可以讓本地強(qiáng)緩存失效
只用在客戶端發(fā)送的請求中”廾耍客戶端會要求所有的中間服務(wù)器不返回緩存的資源圾结。 - Expires: 服務(wù)端配置的,屬于強(qiáng)緩存齿诉,?用來控制在規(guī)定的時(shí)間之前筝野,瀏覽器?不會發(fā)出請求晌姚,?是直接使?用本地緩存,Expires一般對應(yīng)服務(wù)?端時(shí)間歇竟,如 Expires : Fri , 30 Oct 1998 14:19:41
- Cache-Control:通用首部字段挥唠,HTTP1.1中啟用Cache-Control來控制頁面的強(qiáng)緩存與否,指令參數(shù)是可選的焕议,多個(gè)指令之間通過“,”分割
Cache-Control: private, max-age=0, no-cache
關(guān)于no-cach和no-store的說明
no-cache表示不使用 Cache-Control的緩存控制方式做前置驗(yàn)證宝磨,而是使用 Etag 或者Last-Modified字段來控制緩存
no-store ,真正的不緩存任何東西号坡。瀏覽器會直接向服務(wù)器請求原始文件懊烤,并且請求中不附帶 Etag 參數(shù)(服務(wù)器認(rèn)為是新請求)。
1.1Cache-Control:max-age 的優(yōu)先級高于1.0Expires
Expires 使?的是服務(wù)器端的時(shí)間宽堆,有時(shí)候會有這樣一種情況-客戶端時(shí)間和服務(wù)端不同步腌紧。這樣可能會造成瀏覽?本地的緩存無?或者?直?法過期,所以http1.1后不推薦使?Expires畜隶。? Max-Age使?的是客戶端本地時(shí)間計(jì)算壁肋,不會有這個(gè)問題。
應(yīng)用 HTTP/1.1 版本的緩存服務(wù)器遇到同時(shí)存在 Cache-Control:max-age 和Expires 首部字段的情況時(shí)籽慢,會優(yōu)先處理理 max-age 指令浸遗,而忽略 Expires 首部字段。
1.1Cache-Control和1.0Pragma
Pragma 是 HTTP/1.1 之前版本的歷史遺留字段箱亿,僅作為與 HTTP/1.0 的向后兼容而定義跛锌。因此,發(fā)送的請求會同時(shí)含有下面兩個(gè)首部字段届惋。
Cache-Control: no-cache
Pragma: no-cache
5.2.2 協(xié)商緩存
(http1.0) If-Modified-Since/Last-Modified
(http1.1) If-None-Match/E-tag
-
If-Modified-Since:告知服務(wù)器若 If-Modified-Since 字段值早于資源的更新時(shí)間Last-Modified髓帽,則希望能處理該請求。而在指定 If-Modified-Since 字段值的日期時(shí)間之后脑豹,如果請求的資源都未有過更新郑藏,則返回狀態(tài)碼 304 Not Modified。
- If-None-Match:指定當(dāng) If-None-Match 字段值的實(shí)體標(biāo)記(ETag) 值與請求資源的 ETag 不一致時(shí),它就告知服務(wù)器處理該請求俱饿。
- Last-Modified :
1.表明服務(wù)端的?文件最后何時(shí)改變的
2.缺陷1:就是只能精確到1s歌粥,
3.缺陷2:有的服務(wù)端的?件會周期性的改變,導(dǎo)致緩存失效 - E-tag:
1.是一種指紋機(jī)制拍埠,代表文件相關(guān)指紋
2.只有文件變才會變失驶,也只要?件變就會變,
3.沒有精確時(shí)間的限制械拍,只要?件?改變突勇,E-tag就不一樣了
1.1E-tag相?比1.0Last-Modified
Etag 主要為了解決 Last-Modified 無法解決的一些問題装盯。
- 一些文件也許會周期性的更改,但是他的內(nèi)容并不改變(僅僅改變的修改時(shí)間)甲馋,這個(gè)時(shí)候我們并不希望客戶端認(rèn)為這個(gè)文件被修改了埂奈,而重新GET;
- 某些文件修改非常頻繁,比如在秒以下的時(shí)間內(nèi)進(jìn)行修改定躏,(比方說1s內(nèi)修改了N次)账磺,If-Modified-Since能檢查到的粒度是s(秒)級的,這種修改無法判斷痊远。
- 某些服務(wù)器不能精確的得到文件的最后修改時(shí)間垮抗;
為此,HTTP/1.1引入了 Etag(Entity Tags實(shí)體標(biāo)記).Etag僅僅是一個(gè)和文件相關(guān)的標(biāo)記, 比如說v1.0.0或者說"2e681a-6-5d044840"這么一串看起來很神秘的編碼碧聪。但是HTTP/1.1標(biāo)準(zhǔn)并沒有規(guī)定Etag的內(nèi)容是什么或者說要怎么實(shí)現(xiàn)冒版。
5.3 瀏覽器使用緩存的工作流程
瀏覽器在第一次請求發(fā)生后,再次請求時(shí):
- 瀏覽器會先獲取該資源緩存的header信息逞姿,根據(jù)其中的expires和cahe-control判斷是否命中強(qiáng)緩存
- 若命中則直接使用本地緩存辞嗡,不用請求服務(wù)器。
- 如果沒有命中強(qiáng)緩存滞造,瀏覽器會發(fā)送請求到服務(wù)器续室,該請求會攜帶第一次請求返回的有關(guān)緩存的header字段信息(Last-Modified/IF-Modified-Since、Etag/IF-None-Match),由服務(wù)器根據(jù)請求中的相關(guān)header信息來對比結(jié)果是否命中協(xié)商緩存
- 若命中谒养,則服務(wù)器返回新的響應(yīng)header信息更新緩存中的對應(yīng)header信息挺狰,但是并不返回資源內(nèi)容,它會告知瀏覽器可以直接從緩存獲嚷蚩摺丰泊;
- 未命中,從服務(wù)器返回最新的資源內(nèi)容
6 Web安全之攻擊技術(shù)
對 Web 應(yīng)用的攻擊模式有以下兩種蔑祟。
- 主動(dòng)攻擊
攻擊者通過直接訪問 Web 應(yīng)用趁耗,把攻擊代碼傳入的攻擊方式沉唠。由于該方式是直接針對服務(wù)器上的資源進(jìn)行攻擊疆虚,因此攻擊者需要能夠訪問到那些資源。例如SQL注入攻擊和OS命令注入攻擊 - 被動(dòng)攻擊
利用圈套策略行攻擊代碼的攻擊模式满葛。攻擊者不直接對目標(biāo) Web 應(yīng)用訪問發(fā)起攻擊径簿。例如XSS和CSRF。
6.1 什么是 XSS 攻擊嘀韧?如何預(yù)防篇亭?
XSS( Cross site scripting,跨站腳本攻擊)利用的是瀏覽器可以拼接成任意的javascript,然后攻擊者編寫惡意腳本(即拼接好javascript)讓瀏覽器自動(dòng)地給服務(wù)器端發(fā)出多個(gè)請求(get锄贷、post請求)译蒂,當(dāng)其他用戶在自己瀏覽器上運(yùn)行時(shí)曼月,一不小心就會遭到被動(dòng)攻擊。簡單來說就是惡意用戶 H 提交惡意腳本柔昼,顯示在另一個(gè)用戶 B 的網(wǎng)頁上哑芹,對 B 的網(wǎng)頁隨意篡改。
6.1.1造成 XSS 有幾個(gè)要點(diǎn):
- 惡意用戶可以提交內(nèi)容
- 提交的內(nèi)容可以顯示在另一個(gè)用戶的頁面上
- 這些內(nèi)容未經(jīng)過濾捕透,直接運(yùn)行在另一個(gè)用戶的頁面上
6.1.2 XSS可能造成以下影響:
利用虛假輸入表單騙取用戶個(gè)人信息
竊取用戶Cookie信息
6.1.3 XSS攻擊舉例說明
假設(shè)我們有一個(gè)評論系統(tǒng)聪姿。
用戶 A 提交評論「小谷你好」到服務(wù)器,然后用戶 B 來訪問網(wǎng)站乙嘀,看到了 A 的評論「小谷你好」末购,這里沒有 XSS。
惡意用戶 H 提交評論「<script>console.log(document.cookie)</script>」虎谢,然后用戶 B 來訪問網(wǎng)站盟榴,這段腳本在 B 的瀏覽器直接執(zhí)行,惡意用戶 H 的腳本就可以任意操作 B 的 cookie婴噩,而 B 對此毫無察覺曹货。有了 cookie,惡意用戶 H 就可以偽造 B 的登錄信息讳推,隨意訪問 B 的隱私了顶籽。而 B 始終被蒙在鼓里。
6.1.4 預(yù)防XSS的3個(gè)方法
- 不要使用 innerHTML银觅,改成 innerText礼饱,這樣script 就會被當(dāng)成文本,不會執(zhí)行
- 如果你一定要用 innerHTML究驴,就要把可疑符號變成 HTML 實(shí)體
把 < 替換成 <
把 > 替換成 >
把 & 替換成 &
把 " 替換成 '
把 ' 替換成 "
代碼 div.innerHTML = userComment.replace(/>/g, '<').replace...
- Chrome瀏覽器使用 CSP (Content Security Policy內(nèi)容安全策略)
CSP通過黑白名單的機(jī)制控制資源加載(或執(zhí)行腳本)镊绪。
6.2 什么是 CSRF 攻擊?如何預(yù)防洒忧?
CSRF(Cross Site Request Forgery, 跨域請求偽造)利用的是網(wǎng)站服務(wù)器端所有參數(shù)都是可預(yù)先構(gòu)造的原理蝴韭,然后黑客拼接好具體請求url(構(gòu)造網(wǎng)站后臺某個(gè)功能接口的請求地址,即設(shè)置好陷阱)熙侍,利用已通過認(rèn)證的用戶權(quán)限榄鉴,誘導(dǎo)用戶去點(diǎn)擊或者用特殊方法讓該請求地址自動(dòng)加載,在受害者毫不知情的情況下以受害者名義偽造請求發(fā)送給受攻擊站點(diǎn)蛉抓。由于用戶在登錄狀態(tài)下庆尘,所以這個(gè)請求被服務(wù)端接收后會被誤以為是用戶合法的操作。
6.2.1 CSRF攻擊過程
1.用戶訪問瀏覽正常網(wǎng)站
2.正常網(wǎng)站服務(wù)器響應(yīng)并且返回標(biāo)識該用戶身份的cookie
3.用戶未注銷正常網(wǎng)站的情況下巷送,訪問惡意網(wǎng)站
4.惡意網(wǎng)站里訪問正常網(wǎng)站并且?guī)е鴺?biāo)識用戶的cookie
5.正常網(wǎng)站服務(wù)器接受來自惡意網(wǎng)站的請求
6.2.2 CSRF攻擊舉例說明
a.用戶在 qq.com 登錄
b.攻擊者設(shè)置好陷阱驶忌,誘導(dǎo)用戶切換到 hacker.com(惡意網(wǎng)站)
c.hacker.com 發(fā)送一個(gè) qq.com/add_friend 請求,讓當(dāng)前用戶添加 hacker 為好友笑跛。 雖然有跨域付魔,但跨域并不阻止發(fā)送請求聊品,只阻止接受響應(yīng)
d.用戶在不知不覺中添加 hacker 為好友。
e.用戶沒有想發(fā)這個(gè)請求几苍,但是 hacker 偽造了用戶發(fā)請求的假象杨刨。
6.2.3 預(yù)防的2個(gè)方法
1.檢查 http referer字段
(HTTP Referer是header的一部分,它記錄了該 HTTP 請求的來源地址)擦剑,qq.com 可以拒絕來自 hacker.com 的請求妖胀。
優(yōu)點(diǎn):簡單易行,只需要在最后給所有安全敏感的請求統(tǒng)一增加一個(gè)攔截器來檢查 Referer 的值就可以惠勒。
缺點(diǎn):1.Referer 的值是由瀏覽器提供的赚抡,使用驗(yàn)證 Referer 值的方法,就是把安全性都依賴于瀏覽器來保障纠屋,理論上來講涂臣,這樣并不安全。事實(shí)上售担,對于某些瀏覽器赁遗,比如 IE6 或 FF2,目前已經(jīng)有一些方法可以篡改 Referer 值族铆。
2.由于Referer 值會記錄下用戶的訪問來源岩四,有些用戶認(rèn)為這樣會侵犯到他們自己的隱私。因此哥攘,用戶自己可以設(shè)置瀏覽器使其在發(fā)送請求時(shí)不再提供 Referer剖煌。網(wǎng)站不能因?yàn)檎埱鬀]有 Referer 值而認(rèn)為是 CSRF 攻擊,從而拒絕合法用戶的訪問逝淹。
2.添加校驗(yàn) csrf_token 來解決
- 當(dāng)用戶正常訪問網(wǎng)站時(shí)耕姊,服務(wù)器會生產(chǎn)一個(gè)隨機(jī)數(shù)token,并且把該隨機(jī)數(shù)埋入該頁面里(一般放在form表單栅葡,<input type="hidden" name="_csrf_token" value="xxxx">)發(fā)送給客戶端茉兰。
- 正常訪問,客戶的瀏覽器能夠得到該token欣簇。
- 客戶端提交請求時(shí)规脸,需要返回該token到服務(wù)器(對于 GET 請求,token 將附在請求地址之后醉蚁,這樣 URL 就變成
http://url?csrftoken=tokenvalue
燃辖。對于 POST 請求來說鬼店,要在 form 的最后加上<input type=”hidden” name=”csrftoken” value=”tokenvalue”/>
)网棍。 - 服務(wù)端檢測這個(gè)TOKEN是否是合法的(把請求中的 token 與session 中的 token 進(jìn)行比對(解析請求的cookie獲取sessionid,獲取session中_csrf_token的值妇智,然后和用戶請求提交的_csrf_token做個(gè)比較滥玷,如果相等表示請求是合法的)氏身,如果不合法就有可能是黑客偽造用戶信息進(jìn)行請求的。