Etag緩衝在PHP和NodeJS中的實現

來源:互聯網
上載者:User

標籤:style   blog   class   code   java   c   

HTTP 提供了許多頁面緩衝的方案,其中屬 Etag 和 Last-Modified 應用最廣。本文會先介紹 Etag 的應用情境,然後說說他在 php 和 node 中的使用。

本文地址:http://www.cnblogs.com/hustskyking/p/etag-in-node.html,轉載請註明源地址。

一、Etag的使用

用戶端和瀏覽器之間的互動:

+---------+       1         +---------+|         |---------------->|         ||         |   2(200,OK)   |         ||         |<----------------|         ||    客   |    3(Etag)     |    服   ||         |---------------->|         ||    戶   |    4(304)      |    務   ||         |<----------------|         ||    端   |    3(強制重新整理)  |    端   ||         |---------------->|         ||         |   6(200,OK)   |         ||         |<----------------|         |+---------+                 +---------+                <Created By Barret Lee>

1. 用戶端向伺服器請求資源S

2. 伺服器返回資料,並帶上一個 Etag

3. 用戶端再次請求資源S,由於上次伺服器給他返回了一個 Etag,這次請求的時候他會帶上這個 Etag

4. 伺服器發現請求中包含 Etag,判斷是否到期,沒到期則返回 304 Not Modified

5. 用戶端強制重新整理(如chrome中ctrl+shift+R重新整理頁面),請求中剔除 Etag

6. 伺服器未發現請求中包含 Etag,返回資源S,並帶上一個 Etag

二、代碼實現

第一次請求資料:

瀏覽器在接受到伺服器發過來的 Etag 後,會儲存下來,下次請求的時候會將它放在要求標頭中,其 key 值為 If-None-Match。

伺服器拿到 If-None-Match 之後,對比之前的 Etag,如果沒變,則返回 304 Not Modified.

1. php 中的 Etag
<?php    $str = "Barret Lee";    $Etag = md5($str);    if(array_key_exists(‘HTTP_IF_NONE_MATCH‘, $_SERVER) and $_SERVER[‘HTTP_IF_NONE_MATCH‘] == $Etag){        header("HTTP/1.1 304 Not Modified");        exit();    } else {        header("Etag:" . $Etag);        echo $str;    }?>

Etag 是一個字串,我們一般使用該請求對應響應輸出的 md5 值作為 Etag,可以簡單地理解為檔案的版本號碼。在 php 中存在兩個擷取 md5 的函數,一個是針對字串的,就是 md5(),然後就是針對檔案的, md5_file()

首先判斷在請求中是否包含 ‘HTTP_IF_NONE_MATCH‘ 這個 key,如果包含並且其值為之前的 md5 值,則返回 304,否則輸出 Etag 以及內容。

2. node 中的 Etag

與 php 有些不同,從 $_SERVER 中拿到的內容是經過 apache 封裝過的,而 node 擷取的資料是最原始的。

var hashStr = "A hash string.";var hash = require("crypto").createHash(‘sha1‘).update(hashStr).digest(‘base64‘);require("http").createServer(function(req, res){    if(req.headers[‘if-none-match‘] == hash){        res.writeHead(304);        res.end();        return;    }    res.writeHead(200, {        "Etag": hash    })    res.write(hashStr);    res.end();}).listen(9999);

上面對 hashStr(輸出的內容) 進行了簡單的處理,並將其作為 Etag 放在 head 中輸出,上面的代碼一目瞭然,我就不解釋了。

三、小結

Etag 在緩衝處理中用的比較廣泛,使用它可以減少一些不必要請求的頻寬的佔用。伺服器輸出的內容不變,瀏覽器就應該使用緩衝,沒必要每次都向伺服器端索要資料,造成不必要的浪費。

從上面我們可以看到,如果想拿到 Etag,就必須先拿到要輸出的資料,所以 Etag 只能減少頻寬的佔用,並不能降低伺服器的消耗。如果是靜態頁面,可以判斷檔案最近一次的修改時間(Last-Modified),擷取檔案上次修改時間的消耗比拿到整個資料的消耗要小的多。所以很多時候 Etag 都是配合這 Last-Modified 一起使用的。

上面的 php 和 node 代碼示範,很明顯的差異就是,node 更加細緻,或者說他更加底層,我們可以擷取的幾乎都是未加修飾的未經處理資料,從資料量的互動和可操控性來看,我更偏向於 node 的使用。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.