輸入url到頁面顯示發(fā)生了什么
- 第一步 redirect(跳轉(zhuǎn))
會做一個redirect猿规,問什么呢像棘,因為瀏覽器可能記錄了你所訪問的地址夭谤,并且永久跳轉(zhuǎn)到一個新的地址港粱,所以一開始瀏覽器就要去判斷需不需要redirect以及我要redirect到哪里搀菩。 - 第二步 App cache(應(yīng)用緩存)
請求的資源可能已經(jīng)緩存過了呕臂,如果沒有緩存,才會真正的去發(fā)送請求肪跋。 - 第三步 DNS解析
域名會被解析成ip地址歧蒋,找到響應(yīng)的服務(wù)器。 - 第三步 創(chuàng)建TCP連接
如果是普通的http請求州既,會有三次握手谜洽;如果是https請求又不一樣,中間會有保證安全的數(shù)據(jù)傳輸?shù)倪^程吴叶。 - 第四步 Request發(fā)送請求
此時連接創(chuàng)建完畢后就會真正的發(fā)送http數(shù)據(jù)包阐虚。 - 第五步 Response接收響應(yīng)
后端接收數(shù)據(jù)進(jìn)行處理最后返回數(shù)據(jù)。
網(wǎng)絡(luò)協(xié)議分層
- TCP/IP協(xié)議是一個很重要的協(xié)議蚌卤,要創(chuàng)建一個HTTP的服務(wù)或者FTP的服務(wù)实束,這些服務(wù)都是基于TCP協(xié)議的基礎(chǔ)上實現(xiàn)的。
- 傳輸層
- 向用戶提供可靠的端到端(end-to-end)服務(wù)造寝。
- 比如自己的電腦和百度之間如何進(jìn)行傳輸磕洪,傳輸?shù)臄?shù)據(jù)有大有小,如果數(shù)據(jù)很大就要進(jìn)行分包诫龙、分片析显,分包和分片數(shù)據(jù)到另一端的時候如何去傳輸、組裝都是由傳輸層來定義的签赃。
- 傳輸層向高層屏蔽了下層數(shù)據(jù)的通信細(xì)節(jié)谷异。
- 數(shù)據(jù)傳輸分尸,分包、分片歹嘹、組裝是怎么實現(xiàn)的箩绍,在應(yīng)用層(也就是http層)是不需要關(guān)心的,傳輸層已經(jīng)幫我們封裝好了尺上。
- 向用戶提供可靠的端到端(end-to-end)服務(wù)造寝。
- 應(yīng)用層
- 為應(yīng)用軟件提供了很多服務(wù)
- 構(gòu)建于TCP協(xié)議之上
- 屏蔽了網(wǎng)絡(luò)傳輸相關(guān)細(xì)節(jié)
http的歷史
-
http/0.9
- 只有一個get命令:我們用的get請求材蛛、post請求統(tǒng)稱為http的命令或者方法。
- 沒有header等描述數(shù)據(jù)的信息
- 服務(wù)器發(fā)送完數(shù)據(jù)后怎抛,就關(guān)閉了TCP連接卑吭。
- TCP連接里面可以發(fā)送多個http請求,http請求是在某一個tcp連接中去發(fā)送的马绝。
-
http/1.0(和http1.1很相近)
- 增加了一些命令豆赏;如post、put富稻、header等
- 增加了status code和header(請求頭響應(yīng)頭掷邦,里面可以有數(shù)據(jù)相關(guān)的描述)
- 多字符集支持、多部分發(fā)送椭赋、權(quán)限抚岗、緩存等。
-
http1.1(在http1.0的基礎(chǔ)上增加了一些功能來優(yōu)化整個連接的過程)
- 支持持久連接(http1.0發(fā)送一個http請求會先建立一個tcp連接纹份,但是接收完數(shù)據(jù)后連接會關(guān)閉苟跪,下次發(fā)請求要重新建立連接,建立連接要經(jīng)過tcp的三次握手蔓涧,比較消耗性能件已,如果能夠復(fù)用,性能會得到很大的優(yōu)化元暴,持久連接就是http請求完成后tcp連接不會關(guān)閉篷扩,可以繼續(xù)在這個連接上發(fā)送其他http請求)
- pipeline (一個tcp連接可以串行發(fā)送多個請求,服務(wù)端會根據(jù)請求過來的順序一個一個返回茉盏,后一個請求要等待前一個請求返回完成才可以發(fā)送鉴未,不能并行,在http2會做優(yōu)化)
- 增加host和其他一些命令(有了host鸠姨,一個后臺服務(wù)器【物理服務(wù)器】就可以同時部署多個web服務(wù))
-
http2
- 所有的數(shù)據(jù)以二進(jìn)制進(jìn)行傳輸(http1.0大部分?jǐn)?shù)據(jù)都是通過字符串傳輸?shù)耐眩址畟鬏敽投M(jìn)制數(shù)據(jù)傳輸分片方式是不一樣的,在http2.0中數(shù)據(jù)都是以幀進(jìn)行傳輸?shù)难惹ǎ舱且驗檫@個原因连茧,同一個連接里面發(fā)送多個請求不需要再按照順序來)
- 同一個連接里面發(fā)送多個請求不需要再按照順序來
- 頭信息壓縮以及推送等提高效率的功能。(在http1頭信息中很多字段,比如content-type啸驯、cache-conteol等等都是以字符串形式保存的客扎,占用帶寬的量比較大,http2會對其進(jìn)行壓縮罚斗,減少帶寬)
- 服務(wù)端主動推送(http1請求一個頁面徙鱼,服務(wù)器會先返回頁面,瀏覽器解析了頁面以后针姿,再去請求需要的css袱吆、js等資源;到了http2服務(wù)器在返回頁面的同時把css搓幌、js等資源推送到客戶端)
- https(就是一個安全版本的http1.1)
TCP連接和http的關(guān)系
- http不存在連接的概念杆故,只存在請求和響應(yīng);要發(fā)送http請求溉愁,必須先創(chuàng)建tcp連接。之后才可以發(fā)送請求饲趋。
- 長連接和短連接的區(qū)別是:短連接是在發(fā)送http請求的時候創(chuàng)建連接拐揭,請求完就關(guān)閉連接;長連接是先聲明一個連接奕塑,然后發(fā)送http請求堂污,請求完成后連接不會關(guān)閉。
TCP連接三次握手
- 為什么要有三次握手龄砰?它的作用是什么盟猖?
- 客戶端和服務(wù)端之間要創(chuàng)建連接,如果客戶端只發(fā)送了一次請求换棚,服務(wù)端就創(chuàng)建連接了式镐,可能會存在一個問題:當(dāng)服務(wù)器把數(shù)據(jù)返回給客戶端的時候,可能因為網(wǎng)絡(luò)原因固蚤,客戶端沒收到娘汞,響應(yīng)時長過了以后,客戶端關(guān)閉了這個連接夕玩;但是服務(wù)端不知道你弦,依然保持著當(dāng)前端口連接等待客戶端發(fā)送請求過來,這樣就會造成不必要的性能開銷燎孟。所以需要客戶端接收到響應(yīng)后再次發(fā)送一個請求禽作,服務(wù)端收到了說明現(xiàn)在網(wǎng)絡(luò)良好,可以傳輸數(shù)據(jù)了揩页。所以三次握手的目的就是規(guī)避由于網(wǎng)絡(luò)延遲造成服務(wù)端產(chǎn)生不必要開銷的問題旷偿。
cors預(yù)請求(跨域的時候回出現(xiàn)預(yù)請求的驗證 )
允許的方法有
- GET
- HEAD
- POST
允許的Content-Type有
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
其他限制
- 請求頭限制
- 自定義的請求頭
- XMLHttpRequestUpload對象沒有注冊任何事件監(jiān)聽器
- 請求中沒有使用ReadableStream對象
但我們可以在服務(wù)端設(shè)置允許的請求頭,比如
response.writeHead(200,{
'Access-Control-Allow-Origin' : '*', //允許跨域的域名
'Access-Control-Allow-Headers' : 'custom-Test',//允許跨域的請求頭,可以是自定義的
'Access-Control-Allow-Methods' : 'POST, PUT, Delete',//允許跨域的請求方法
'Access-Control-Max-Age' : '1000'//不需要再次發(fā)送預(yù)請求的最大時間狸捅,單位是秒
});
在跨域的時候衷蜓,會發(fā)現(xiàn)程序?qū)懙闹话l(fā)送了一條請求,但network出現(xiàn)了兩條尘喝,其中一條請求頭的除了Mehods的類型是OPTIONS,其他信息和我們發(fā)出的請求一模一樣磁浇,該請求就是發(fā)送的預(yù)請求。
緩存Cache-Control
可緩存性(哪些地方可以去緩存)
- public 指的是發(fā)送的http請求返回內(nèi)容所經(jīng)過的任何路徑當(dāng)中朽褪,包括一些中間的http的代理服務(wù)器置吓,以及發(fā)出這個請求的客戶端瀏覽器,都可以進(jìn)行對于返回內(nèi)容的緩存的操作缔赠,緩存操作指的就是把這份內(nèi)容緩存在本地衍锚,下一次請求可以直接讀緩存去使用
- private 指的是只有發(fā)起求情的瀏覽器才能夠進(jìn)行緩存
- no-cache 指的是任何節(jié)點(diǎn)都不能進(jìn)行緩存。
到期
- max-age = <seconds>緩存多少秒后過期
- s-maxage = <seconds>只在代理服務(wù)器才生效嗤堰,同時設(shè)置max-age和s-max-age,s-max-age會代替maxage戴质;是專門為代理服務(wù)器設(shè)置的,客戶端瀏覽器還是讀取max-age作為緩存的時間踢匣。
- max-stale = <seconds>max-age是發(fā)起請求的一方主動帶的請求頭告匠,在max-age過期之后,如果返回的資源中有max-stale的設(shè)置离唬,代表即便緩存過期了后专,但是只要是在max-stale的時間內(nèi),還可以使用過期的緩存输莺,而不需要去源服務(wù)器去請求新的內(nèi)容戚哎,只有在發(fā)起端設(shè)置是有用的,服務(wù)端設(shè)置是沒有用的嫂用。
重新驗證
- must-revalidate 在設(shè)置了max-age的緩存當(dāng)中型凳,如果過期了,必須從服務(wù)端尸折,源服務(wù)端去方請求重新獲取數(shù)據(jù)驗證內(nèi)容是否真的過期了啰脚,而不能直接使用本地的緩存。
- proxy-revalidate 和must-revalidate基本一個意思实夹,不過是作用于緩存服務(wù)器當(dāng)中的橄浓,在過期后,緩存服務(wù)器必須從源服務(wù)器請求一遍亮航,而不能使用本地的緩存荸实。
其他
- no-store 要和no-cache做一個區(qū)分,no-cache是可以在本地進(jìn)行緩存的缴淋,也可以在代理服務(wù)器進(jìn)行緩存准给,但每次發(fā)起請求都要去服務(wù)器那邊做驗證泄朴,如果服務(wù)器返回告訴可以用本地的緩存,然后請求方才能去使用緩存露氮。no-store指本地和代理服務(wù)器都不可以緩存祖灰,打個不恰當(dāng)?shù)谋确剑词垢嬖V瀏覽器可以使用緩存畔规,瀏覽器本地也沒有緩存局扶。
-
no-transform 作用于代理服務(wù)器,有些代理服務(wù)器覺得返回的資源太大了叁扫,代理服務(wù)器會進(jìn)行一些壓縮三妈,進(jìn)行一些格式轉(zhuǎn)換,通過no-transform禁止代理服務(wù)器的這種行為莫绣。
image.png
驗證
- Last-Modifiled 上次修改時間畴蒲,配合If-Modified-Since或者If-Unmodified-Since使用
我們請求一個資源,請求的資源返回了Last-Modifield頭信息对室,指定了一個時間模燥,這個時間在下一次瀏覽器發(fā)起請求的時候就會帶上Last-Modifield傳過來的值,比如值為val软驰,那么瀏覽器會設(shè)置頭信息If-Modified-Since或者If-Unmodified-Since涧窒,一般瀏覽器都是使用If-Modified-Since,If-Unmodified-Since很少會被用到锭亏,頭信息的值就是val,服務(wù)器可以通過讀取request的頭信息硬鞍,找到資源存在的地方慧瘤,找到其修改的時間,如果發(fā)現(xiàn)這兩個時間是一致的固该,代表該資源未被修改過锅减,然后就告訴瀏覽器可以使用緩存的資源,如果不一致伐坏,就返回新的資源怔匣。 - Etg 是一種更加嚴(yán)格的驗證,通過數(shù)據(jù)簽名 桦沉,配合If-Match或者If-Non-Match使用每瞒,我們的資源,也就是內(nèi)容會產(chǎn)生一個唯一的簽名纯露,如果資源的數(shù)據(jù)進(jìn)行過修改剿骨,那么簽名就會產(chǎn)生一個新的,最典型的做法就是會對資源的內(nèi)容進(jìn)行一個hash計算得到一個唯一值埠褪。也就是瀏覽器在請求一個資源的時候響應(yīng)頭會返回該資源的簽名值浓利,下次瀏覽器去請求的時候會帶上頭信息If-Match或者If-Non-Match挤庇,服務(wù)器收到后會和現(xiàn)在該資源的簽名去做對比,如果一致贷掖,就不需要返回新的內(nèi)容嫡秕。
const http = require('http');
const fs = require('fs');
http.createServer(function (request, response) {
console.log('request come',request.url);
if(request.url == '/'){
const html = fs.readFileSync('test.html','utf-8');
response.writeHead(200,{
'Content-Type':'text/html'
});
response.end(html);
}
if(request.url == '/script.js'){
const etag = request.headers['if-none-match'];
if(etag === '777'){
/**
* 1.當(dāng)寫入頭為304的時候,即使我們把Etag的值改變了苹威,瀏覽器也不會重新拿到新資源昆咽,
* 也不會更新響應(yīng)頭返回的Etag的新值,所以下次請求的時候用的還是老的Etag的值屠升。
* 2.當(dāng)設(shè)置Cache-Control的值no-cache時候潮改,如果響應(yīng)頭返回了Last-Modified和Etag的值,
* 瀏覽器再次發(fā)送請求的時候會添加Last-Modified和Etag的請求頭腹暖;
* 當(dāng)設(shè)置Cache-Control的值no-cache時候汇在,即使應(yīng)頭返回了Last-Modified和Etag的值,
* 瀏覽器再次發(fā)送請求也不會添加Last-Modified和Etag的請求頭脏答;
**/
response.writeHead(304,{
'Content-Type':'application/javascript',
'Cache-Control':'max-age=2000000,no-store',
'Last-Modified':'123',
'Etag':'7778'
});
response.end('some word')
}else{
response.writeHead(200,{
'Content-Type':'application/javascript',
'Cache-Control':'max-age=2000000,no-store',
'Last-Modified':'123',
'Etag':'777'
});
response.end('console.log("script loaded twice")');
}
}
}).listen(8888);
console.log('service listening on 8888');
Cookie
- 通過Set-Cookie設(shè)置 :Cookie是在服務(wù)端返回數(shù)據(jù)的時候通過添加Set-Cookie請求頭設(shè)置在瀏覽器里面保存內(nèi)容的糕殉;保存的內(nèi)容就叫做Cookie。
- 下次求情會自動帶上
- 鍵值對殖告,可以設(shè)置多個
Cookie屬性
- max-age和expires設(shè)置過期時間
- Secure 只在https的時候發(fā)送
- HttpOnly 設(shè)置了HttpOnly屬性以后阿蝶,瀏覽器端就無法通過 document.cookie訪問
const http = require('http');
const fs = require('fs');
http.createServer(function (request, response) {
console.log('request come',request.url);
const host = request.headers.host;
if(request.url == '/'){
const html = fs.readFileSync('./test.html','utf-8');
/**注意,下面代碼我們在a.test.com的域名設(shè)置domain的值為test.com黄绩,其實是不能成功的羡洁,也就是說不能
* 在二級域名下設(shè)置一級域名的cookie;此時cookie不能被設(shè)置成功。
* **/
if(host==='a.test.com'){
response.writeHead(200,{
'Content-Type':'text/html',
'Set-Cookie':['id=123;max-age=2','abc=456;HttpOnly','def=789;domain=test.com']
});
}
response.end(html);
};
}).listen(8888);
console.log('service listening on 8888');
修改代碼
if(host==='test.com'){
response.writeHead(200,{
'Content-Type':'text/html',
'Set-Cookie':['id=123;max-age=2','abc=456;HttpOnly','def=789;domain=test.com']
});
}
此時是可以設(shè)置成功的爽丹,由于設(shè)置的domain的值是一級域名test.com筑煮。那么a.test.com以及b.test.com都會帶上所設(shè)置的cookie。
Http長連接
發(fā)送http請求需要創(chuàng)建TCP連接粤蝎,在http0.9和http1.0的時候每發(fā)送一次請求都需要建立創(chuàng)建一個TCP的連接真仲,請求響應(yīng)后這個連接就會關(guān)閉,下次發(fā)請求會重新創(chuàng)建TCP連接初澎;http1.1之后包括http1.1是支持長連接的秸应,意思是只創(chuàng)建一次TCP連接敬惦,
之后的請求都通過這個連接槽唾。我們打開百度,隨意輸入一個關(guān)鍵字去搜索瓦盛,打開network截圖如下:
圖中有一列顯示的是connectionID墓懂,connectionID相同表明是同一個TCP連接焰宣。http1.1的連接在TCP上發(fā)送請求是有先后順序的,不能在同一個TCP連接上去并發(fā)的發(fā)送捕仔。我們在加載首頁的時候是希望去并發(fā)的匕积,因為這樣效率會高一點(diǎn)盈罐;所以瀏覽器可以允許并發(fā)的創(chuàng)建TCP連接,數(shù)目會有限制闪唆,比如chrome瀏覽器限制的數(shù)量為6盅粪;
圖中可以看出,connectionID為93370的TCP連接發(fā)送了三次請求悄蕾,后一次請求要等待前一次的返回票顾。
數(shù)據(jù)協(xié)商
分類
- 請求
1.Accept通過Accept 聲明瀏覽器想要的數(shù)據(jù)
2.Accept-Encoding 代表數(shù)據(jù)的編碼方式,主要限制服務(wù)端如何進(jìn)行數(shù)據(jù)壓縮帆调,比如gzip,deflate,br
3.Accept-Language
4.User-Agent -
返回
1.Content-Type
2.Content-Encoding
3.Content-Language
image.png
Redirect
const http = require('http');
http.createServer(function (request, response) {
console.log('request come',request.url);
if(request.url=='/'){
response.writeHead(301,{
'Location':'/new'
});
response.end('');
}
if(request.url=='/new'){
response.writeHead(200,{
'Content-Type':'text/html'
});
response.end('<h3>this is content</h3>');
}
}).listen(8888);
console.log('service listening on 8888');
301(臨時重定向)和302(永久重定向)區(qū)別是 302會先發(fā)送請求到服務(wù)端奠骄,服務(wù)端返回之后瀏覽器再次發(fā)送請求,一共發(fā)送了兩次請求番刊;302是服務(wù)端高告知瀏覽器如果再次出現(xiàn)某個資源的請求路徑含鳞,直接在瀏覽器端改變求情資源的地址,所以只會發(fā)送一次請求芹务。要特別注意的是蝉绷,一旦做了301的跳轉(zhuǎn),瀏覽器會盡可能長時間的去做緩存枣抱,即使之后服務(wù)端修改了響應(yīng)頭熔吗,改為200,瀏覽器也是無感知的佳晶,除非是客戶端用戶自己手動清理瀏覽器的緩存才能得到新的響應(yīng)資源桅狠,所以使用301一定要慎重。
CSP Content-Security-Policy 內(nèi)容安全策略
作用
- 限制資源獲取
- 報告資源獲取越權(quán)
限制方式
- default-src限制全局 限制跟請求鏈接的作用范圍
- 制定資源類型
類型種類很多轿秧,比如:default-src(全局的限制垂攘,包括img資源、css資源淤刃、js資源等等) , content-src 吱型,img-src , mainfest-src , font-src , media-src ,
style-src , frame-src , script-src ...
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>scp</h3>
<script>
console.log('scp test...')
</script>
<script src="/test.js"></script>
<script src="http://code.jquery.com/jquery-3.2.1.min.js"></script>
</body>
</html>
服務(wù)端 service.js
const http = require('http');
const fs = require('fs');
http.createServer(function (request, response) {
console.log('request come',request.url);
const html = fs.readFileSync('./test.html','utf-8');
if(request.url==='/'){
response.writeHead(200,{
'Content-Type':'text/html',
//只允許通過外鏈加載的js執(zhí)行
// 'Content-Security-Policy':'default-src http: https:'
// 只允許通過外鏈的從本域加載的js執(zhí)行
'Content-Security-Policy':'default-src \'self\''
//只允許通過外鏈的從本域或者 http://code.jquery.com/加載的js執(zhí)行
// 'Content-Security-Policy':'default-src \'self\' http://code.jquery.com/'
});
response.end(html);
}else{
response.writeHead(200,{
'Content-Type':'application/javascript'
});
response.end('console.log("loaded script")');
}
}).listen(8888);
console.log('service listening on 8888');
Content-Security-Policy的設(shè)置可以在服務(wù)端逸贾,亦可以在客戶端返回的html文檔。
nginx代理
- 下載安裝http://nginx.org/en/download.html
image.png
下載后解壓
目錄結(jié)構(gòu)如下:
image.png
配置文件在conf下面的nginx.conf文件中津滞,我們建一個servers文件夾
在下面配置需要代理的域名铝侵。
文件nginx.conf中加入
include servers/*.conf;
表明include servers文件夾下面所有以.conf結(jié)尾的文件。
我們配置一個test.conf內(nèi)容如下
proxy_cache_path cache levels=1:2 keys_zone=my_cache:10m;
server {
listen 80;
server_name test.com;
location / {
proxy_cache my_cache;
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
}
}
server {
listen 80;
server_name a.test.com;
location / {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
}
}
server {
listen 80;
server_name b.test.com;
location / {
http://127.0.0.1:8888 http://127.0.0.1:8888;
proxy_set_header Host $host;
}
}
其中server是指要在電腦上起一個服務(wù)触徐,其端口是80咪鲜,它的server_name即域名為test.com,這個server_name指的就是我們在瀏覽器上面要訪問的hostname撞鹉,nginx會根據(jù)要訪問的hostname來判斷要把服務(wù)啟動在什么地方疟丙,代理到什么地方颖侄。比如上面配置了test.com,說明要訪問的地址是test.com享郊,然后test.com被代理到的服務(wù)是http://127.0.0.1:8888览祖。(要記得在hosts文件中配置test.com的映射地址,如127.0.0.1)炊琉;之后我們寫后端服務(wù)展蒂。
service.js代碼如下
const http = require('http');
const fs = require('fs');
const wait = (seconds)=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve();
},seconds*1000);
});
};
http.createServer(function (request, response) {
console.log('request come',request.url);
const host = request.headers.host;
/**
* const html = fs.readFileSync('./test.html','utf-8');
* 此處不能用utf-8編碼,因為utf-8讀取時按照字符串讀取苔咪,使用zlib的話锰悼,
* 希望讀取的是buffer
* */
const html = fs.readFileSync('./test.html');
if(request.url==='/'){
response.writeHead(200,{
'Content-Type':'text/html',
});
response.end(html);
}
if(request.url==='/data'){
/**s-maxage是專門給代理緩存用的,同時使用了max-age=20, s-maxage=20团赏,
* 那么代理緩存會使用s-maxage箕般,瀏覽器會使用max-age。
* **/
response.writeHead(200,{
'Cache-Control':'max-age=2;s-maxage=20'
});
wait(2).then(()=>{
response.end('success')
});
}
}).listen(8888);
console.log('service listening on 8888');
test.html代碼如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>nginx-cache</title>
</head>
<body>
<div>
<span>this is content, and data is: </span>
<span id="data"></span>
</div>
<script>
fetch('/data').then(function (resp) {
return resp.text();
}).then(function (text) {
document.getElementById('data').innerText = text;
})
</script>
</body>
</html>
test.conf的配置是
proxy_cache_path cache levels=1:2 keys_zone=my_cache:10m;
server {
listen 80;
server_name test.com;
location / {
proxy_cache my_cache;
proxy_pass http://127.0.0.1:8888;
}
}
server {
listen 80;
server_name b.test.com;
location / {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
}
}
從代碼中可以看出馆里,在訪問'/'路徑會返回test.html隘世,在test.html中發(fā)起了一個請求,并將結(jié)果文本顯示到頁面上鸠踪。服務(wù)端我們延時了2s去返回請求丙者,并設(shè)置了響應(yīng)頭'Cache-Control':'max-age=2, s-maxage=20',告訴瀏覽器可以緩存結(jié)果2秒(max-age=2)营密,告訴代理服務(wù)器可以緩存20秒(s-maxage=20)械媒。啟用代理服務(wù)緩存還需要在具體的server配置 proxy_cache。參照上面的test.conf评汰。
修改service.js 纷捞,設(shè)置Cache-Control的值為
response.writeHead(200,{
'Cache-Control':'max-age=5,s-maxage=20,private'
});
在瀏覽器端重新刷新,會發(fā)現(xiàn)s-maxage=20將不再生效被去。private是指只有瀏覽器才可以緩存數(shù)據(jù)主儡。
HTTPS 即http+secret
加密
- 私鑰
- 公鑰
公鑰放在互聯(lián)網(wǎng)上所有人都可以拿到的遺傳加密的字符串,這個加密字符串是用來加密我們傳輸?shù)男畔⒌牟依拢褂霉€加密的數(shù)據(jù)傳輸?shù)椒?wù)器之后糜值,只有服務(wù)器通過私鑰進(jìn)行解密才能把公鑰加密過的數(shù)據(jù)解析出來。而私鑰只放在服務(wù)器上坯墨,其他任何人都拿不到私鑰寂汇。所以中間人即便截取了http的消息,但沒有私鑰還是解密不了數(shù)據(jù)的捣染。公鑰和私鑰主要是用在握手的時候進(jìn)行一個傳輸骄瓣,傳輸內(nèi)容是一個正真的在后期傳輸?shù)倪^程中使用的加密字符串,因為加密字符串是使用公鑰私鑰的方式進(jìn)行加密傳輸?shù)乃H粒灾虚g人拿不到加密字符串榕栏,后續(xù)的數(shù)據(jù)傳輸過程中客戶端和服務(wù)端都是用這個加密字符串進(jìn)行數(shù)據(jù)加密傳輸畔勤。