關於HTTP的一些學習

關於HTTP緩存

第一次進入一個網站時,本地無緩存,response成功返回200json

服務器在Response Header裏,設置了Etag和Last-Modify,以下圖;
img數組

Etag字段將資源惟一性的標識,若是資源有更新,Etag值也將變化;瀏覽器

Last-Modify代表了在服務器端最後發生改變的時間;緩存

瀏覽器保存這個Etag值和Last-Modify,以便於下次請求的時候使用;服務器

img

刷新後,發送的Request Header以下:網站

img

其中If-None-Match字段就是向服務器端詢問第一次的Etag值是否更新,兩次Etag相同,說明資源未發生根本改變加密

If-Modified-Since向服務器詢問在這個時間發生改變了嗎;url

img

img

最終發回響應,Etag和Last-Modify無變化,因此最終返回304,比第一次的ResponseHeader相比,還多了兩個字段Cache-Control: max-ageExpiresspa

這兩個屬性就是爲了告訴瀏覽器,沒必要再來詢問服務器資源過沒過時,容許瀏覽器在一個時間段內繼續使用本地緩存;3d

max-age屬於HTTP1.1 ,Expires屬於HTTP1.0,若是max-age和Expires同時存在,Expires則被Cache-Control的max-age覆蓋。

另外返回的ResponseHeader還有Via字段,說明通過了不少代理服務器,這說明咱們要的資源多是放在了CDN上的;

還有個字段Vary,它可對緩存進行控制,它告訴代理服務器,返回和Accept-Encoding字段相同的緩存資源,而不是從源服務器端;

禁用HTTP緩存

no-store不緩存任何內容

no-cache先向服務器驗證緩存

兩種加密方法:

共享密鑰加密(對稱加密):加密解密用同一密鑰,當客戶端發送數據時,用密鑰加密,同時也要把密鑰發給服務器端。這樣形成的問題是密鑰容易被中間攻擊者獲取,也能解密內容;

公開密鑰加密(非對稱加密):加密用公開密鑰加密,解密用私有密鑰解密。其中公開密鑰任何人都能獲取,私有密鑰不公開。當客戶端發送數據時,用公鑰加密,服務器端再用本身的私鑰解密;

HTTPS是在HTTP和TCP之間,再填一層SSL,SSL的基本思想是用非對稱加密來創建連接(握手階段),用對稱加密來傳輸數據(傳輸階段)。這樣作是由於非對稱加密比對稱加密複雜,計算量大,因此只在創建鏈接階段來傳送對稱加密的密鑰;

具體創建鏈接步驟以下:

  • 1.客戶端發送ClientHello報文,告訴服務器端本身支持的SSL版本等信息;
  • 2.服務器端返回ServerHello,告訴瀏覽器本身支持的SSL版本等信息;
  • 3.服務器發送證書給瀏覽器,包含了公鑰;
  • 4.服務器發送SeverHelloDone,完成握手協商;
  • 5.客戶端產生隨機的密碼,做爲對稱加密的密鑰,並用第三步的公鑰加密;
  • 6.之後的信息傳輸都使用第五步的密鑰加密;

HTTP長鏈接

在HTTP1.1中默認開啓長鏈接 connection: keep-alive,這樣是爲了複用TCP,頻繁的HTTP請求會形成頻繁的TCP創建。

使用 connection: keep-alive後,當一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP鏈接不會當即關閉,以後的Ajax請求、靜態文件請求,會繼續使用這一條已經創建的鏈接,可是Keep-Alive不會永久保持鏈接,它有一個保持時間,超過保持時間仍會斷開。

Comet推送

雖然HTTP1.1的TCP鏈接有一個保持時間,超過保持時間會斷開,可是咱們能夠不時地向這條鏈接發送數據,這樣這個鏈接就一直不會斷開。因此能夠用HTTP長鏈接來作一個不使用客戶端輪詢的Comet推送。

採用Node編寫的服務器端代碼:

if (request.url == '/ct' && request.method == "POST") {
    var body="";
    request.on("data", function(chunk) {
        body += chunk;
    });
    request.on("end", function() {
        response.writeHead(200, {
            'Content-Type': "text/event-stream"
        });
        var json={
            'type':'connect'
        }
        json=JSON.stringify(json)
        response.write(json);
        console.log(body)
        response.id=body;
        clients.push(response);       //clients數組保存Response
    });

    request.connection.on("end",function () {  //斷開時刪除對應的Response
        clients.splice(clients.indexOf(response),1);
        response.end();
    })
}



setInterval(function() {
    clients.forEach(function (client) {    //每10000ms發送一次數據來保持HTTP長鏈接不斷開
        var json={
            'type':'event'
        }
        json=JSON.stringify(json)
        client.write(json);
    })
}, 10000);
相關文章
相關標籤/搜索