JR 精品文章 - web開(kāi)發(fā)中的緩存問(wèn)題的研究(二)
| web開(kāi)發(fā)中的緩存問(wèn)題的研究(二) | | wty_703 轉貼 更新:2007-08-09 08:02:25 版本: 1.0 | |
從圖4.16中還可以看到,其“檢查所存網(wǎng)頁(yè)的較新版本”功能項的設置值有4個(gè)選項,只要先單擊“設置”對話(huà)框標題欄中的問(wèn)號按鈕,然后再單擊相應的選項,就可以看到每個(gè)選項的作用和意義:
“每次訪(fǎng)問(wèn)此頁(yè)時(shí)檢查”選項表示瀏覽器每次訪(fǎng)問(wèn)一個(gè)頁(yè)面時(shí),不管瀏覽器是否緩存過(guò)此頁(yè)面,都要向服務(wù)器發(fā)出訪(fǎng)問(wèn)請求。這種設置的優(yōu)點(diǎn)是實(shí)時(shí)性很強,肯定能夠訪(fǎng)問(wèn)到網(wǎng)頁(yè)的最新內容,但是如果網(wǎng)頁(yè)內容很少更新,這種設置的訪(fǎng)問(wèn)效率就比較低了。 “每次啟動(dòng)Internet Explorer時(shí)檢查”選項表示在瀏覽器的每次啟動(dòng)運行期間,在第一次訪(fǎng)問(wèn)一個(gè)頁(yè)面時(shí),不管瀏覽器是否緩存過(guò)此頁(yè)面,都要向服務(wù)器發(fā)出訪(fǎng)問(wèn)請求,但是在瀏覽器的本次啟動(dòng)運行期間對該頁(yè)面的后續訪(fǎng)問(wèn),瀏覽器將不再向服務(wù)器發(fā)出訪(fǎng)問(wèn)請求,而是直接使用緩存中的內容。這種設置具有較高的訪(fǎng)問(wèn)效率,同時(shí)也兼顧了較好的實(shí)時(shí)性,它可以保證每次啟動(dòng)瀏覽器后看到的都是最新的網(wǎng)頁(yè)內容。 “自動(dòng)”選項與“每次啟動(dòng)Internet Explorer時(shí)檢查”選項的功能相似,只是對圖像的訪(fǎng)問(wèn)有所不同,如果隨著(zhù)時(shí)間的推移,瀏覽器發(fā)現網(wǎng)頁(yè)上的圖像更新并不頻繁,這樣,即使瀏覽器在對某個(gè)已緩存的圖像執行本次啟動(dòng)運行以來(lái)的第一次訪(fǎng)問(wèn)時(shí),它也不一定會(huì )向服務(wù)器發(fā)出訪(fǎng)問(wèn)請求,而是干脆直接使用緩存中的內容。“自動(dòng)”選項是瀏覽器的默認設置,所以,幾乎所有人的瀏覽器都是按照這種方式工作的,這個(gè)選項的作用和意義應該成為讀者熟悉的重點(diǎn)。 “不檢查”選項表示瀏覽器不管在什么情況下訪(fǎng)問(wèn)一個(gè)頁(yè)面時(shí),只要能夠在本地找到此頁(yè)面的緩存信息,瀏覽器就不會(huì )向服務(wù)器發(fā)出訪(fǎng)問(wèn)請求,而是直接使用緩存的內容。這種設置的優(yōu)點(diǎn)是訪(fǎng)問(wèn)效率很高,但是如果服務(wù)器端的網(wǎng)頁(yè)內容更新后,瀏覽器看到的內容很可能是過(guò)期的內容。 在瀏覽器的“檢查所存網(wǎng)頁(yè)的較新版本”的功能項采用默認的“自動(dòng)”設置項的情況下,如果瀏覽器剛剛訪(fǎng)問(wèn)過(guò)一個(gè)網(wǎng)頁(yè),服務(wù)器端就更新了這個(gè)網(wǎng)頁(yè)的內容,當瀏覽在關(guān)閉前又重新訪(fǎng)問(wèn)這個(gè)頁(yè)面時(shí),用戶(hù)看到的將不是更新的網(wǎng)頁(yè)內容,而是過(guò)期的網(wǎng)頁(yè)內容。為了提高瀏覽效率,在訪(fǎng)問(wèn)靜態(tài)的網(wǎng)頁(yè)內容時(shí),這么一點(diǎn)小概率的過(guò)期信息還是應該允許的,并且這些過(guò)期信息也不會(huì )造成什么不好的后果,就像你偶爾有一次看到了前一天發(fā)生的新聞,而不是當天的新聞,這又有什么問(wèn)題呢?可是,如果瀏覽器訪(fǎng)問(wèn)的是一個(gè)動(dòng)態(tài)網(wǎng)頁(yè),這本來(lái)就要求瀏覽器在其整個(gè)運行期間的每次訪(fǎng)問(wèn)都能看到最新的內容,例如,銷(xiāo)售一件商品后再回到商品庫存的顯示頁(yè)面時(shí),看到的就應該是更新的庫存數據,而不應該是先前看到的內容。僅僅根據被訪(fǎng)問(wèn)頁(yè)面的資源名稱(chēng),瀏覽器是無(wú)法知道商品庫存的顯示頁(yè)面是屬于動(dòng)態(tài)內容,還是屬于靜態(tài)內容。對于這種情況,瀏覽器將根據響應消息中是否包含Last-Modified頭字段來(lái)進(jìn)行處理,如果響應消息中沒(méi)有包含Last-Modified頭字段,它將在每次訪(fǎng)問(wèn)此頁(yè)面時(shí)都向服務(wù)器發(fā)出訪(fǎng)問(wèn)請求,否則,它僅在每次啟動(dòng)運行后的第一次訪(fǎng)問(wèn)此頁(yè)面時(shí)才向服務(wù)器發(fā)出訪(fǎng)問(wèn)請求,而在啟動(dòng)運行期間對此頁(yè)面的后續訪(fǎng)問(wèn)都不再向服務(wù)器發(fā)出訪(fǎng)問(wèn)請求。 在第2章中曾經(jīng)講解過(guò),響應消息中的Last-Modified頭字段可用于指定響應內容的最后更新時(shí)間,當客戶(hù)機緩存此文檔內容后,它在以后的請求消息中將根據Last-Modified頭字段指定的時(shí)間來(lái)生成If-Modified-Since請求頭字段,以指出緩存文檔的最后更新時(shí)間。只有文檔的修改時(shí)間比If-Modified-Since請求頭指定的時(shí)間新時(shí),服務(wù)器才會(huì )返回文檔內容。如果自從If-Modified-Since指定的時(shí)間以來(lái),網(wǎng)頁(yè)內容沒(méi)有發(fā)生修改,服務(wù)器將返回一個(gè)304(Not Modified)狀態(tài)碼來(lái)表示瀏覽器緩存的版本是最新的,而不會(huì )向瀏覽器返回文檔內容,瀏覽器則繼續使用以前緩存的內容。通過(guò)這種方式,可以在一定程度上減少瀏覽器與服務(wù)器之間的通信數據量,從而提高了通信效率。 HttpServlet類(lèi)為If-Modified-Since請求頭和Last-Modified頭字段的這種應用提供了處理機制,當繼承了HttpServlet類(lèi)的Servlet程序接收到一個(gè)GET方式的訪(fǎng)問(wèn)請求時(shí),HttpServlet中重載的service方法在調用doGet方法之前,它還將調用getLastModified方法,并根據getLastModified方法的返回值來(lái)決定是否調用doGet方法和在響應消息中是否生成Last-Modified頭字段,具體規則如下:
當getLastModified方法返回一個(gè)負數時(shí),不管請求消息中的情況怎樣,service方法都將直接調用doGet方法來(lái)生成響應內容,這正是HTTPServlet類(lèi)中定義的getLastModified方法的行為; 當getLastModified方法返回一個(gè)正數,且請求消息中沒(méi)有包含If-Modified-Since請求頭時(shí)(這往往出現在第對某個(gè)資源的第一次訪(fǎng)問(wèn)時(shí)),或者請求消息中包含的If-Modified-Since請求頭中的時(shí)間值比getLastModified方法返回的時(shí)間值舊時(shí),service方法將根據getLastModified方法的返回值生成一個(gè)Last-Modified頭字段,然后調用doGet方法生成響應內容; 當getLastModified方法返回一個(gè)正數時(shí),且請求消息中包含的If-Modified-Since請求頭中的時(shí)間值比getLastModified方法返回的時(shí)間值新或者與之相同時(shí),service方法將不調用doGet方法,而是向瀏覽器返回一個(gè)304(Not Modified)狀態(tài)碼表示瀏覽器可以使用其以前緩存的內容。 動(dòng)手體驗:揭開(kāi)瀏覽器緩存的奧秘 (1)編寫(xiě)一個(gè)名為CacheServlet的Servlet程序,在其doGet方法中向瀏覽器和Tomcat的命令行窗口中都打印出當前的時(shí)間值,getLastModified方法也是向Tomcat的命令行窗口中打印出當前的時(shí)間值和返回當前時(shí)間值,這里先將getLastModified方法注釋掉,如例程4-9所示。
例程4-9 CacheServlet.java
import java.io.*; import javax.servlet.*; import javax.servlet.http.*;
public class CacheServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); long now = System.currentTimeMillis(); out.println("doGet:" + now); System.out.println("doGet:" + now); } /*protected long getLastModified(HttpServletRequest req) { long now = System.currentTimeMillis(); System.out.println("getLastModified:" + now); return now; }*/ }
編譯CacheServlet.java文件,確保編譯后生成的class文件放置進(jìn)了d:\myweb\WEB-INF\classes目錄中。
(2)在d:\myweb目錄中編寫(xiě)一個(gè)名稱(chēng)為CacheTest.html的網(wǎng)頁(yè)文件,如例程4-10所示。
例程4-10 CacheTest.html
<a href="servlet/CacheServlet">緩存測試</a>
(3)為了便于查看瀏覽器如何生成緩存內容,最好是先刪除掉Internet臨時(shí)文件夾中保存的所有緩存內容。單擊IE瀏覽器的“工具”?“Internet選項”菜單,打開(kāi)如圖4.16所示的“Internet選項”對話(huà)框,接著(zhù)再單擊“常規”選項卡中的“Internet臨時(shí)文件”欄中的“刪除文件”按鈕,這就刪除了Internet臨時(shí)文件夾中保存的所有緩存內容。單擊“常規”選項卡中的“Internet臨時(shí)文件”欄中的“設置”按鈕,在打開(kāi)的“設置”對話(huà)框框中單擊“Internet臨時(shí)文件夾”欄中的“查看文件”按鈕,打開(kāi)如圖4.17所示的Internet臨時(shí)文件夾,可以看到其中已經(jīng)不再有任何緩存的文件。另外,在“設置”對話(huà)框框中還需要將“檢查所存網(wǎng)頁(yè)的較新版本”的功能項恢復為默認的“自動(dòng)”。 在瀏覽器地址欄中輸入如下地址: http://localhost:8080/it315/CacheTest.html 在瀏覽器窗口中顯示的結果頁(yè)面中,單擊“緩存測試”超鏈接訪(fǎng)問(wèn)CacheServlet。再次打開(kāi)Internet臨時(shí)文件夾,這時(shí)可以看到其中生成了剛才訪(fǎng)問(wèn)過(guò)的CacheTest.html和CacheServlet這兩個(gè)頁(yè)面的緩存文件,如圖4.18所示。選中其中的CacheServlet緩存文件,從Windows資源管理器窗口中顯示出的摘要信息中可以看到,CacheServlet緩存文件中記錄的上次修改時(shí)間為“無(wú)”。
圖4.18
(4)在命令行窗口中執行telnet 127.0.0.1 8080命令,連接上Tomcat WEB服務(wù)器后,接著(zhù)在telnet程序命令窗口中,輸入如下內容: GET /it315/servlet/CacheServlet HTTP/1.1<回車(chē)> Host:<空格><回車(chē)> <回車(chē)> telnet窗口中顯示出的結果如圖4.19所示。
圖4.19
從圖4.19中可以看到,CacheServlet返回的響應消息中沒(méi)有Last-Modified頭字段,這正是圖4.18中顯示的CacheServlet緩存文件的上次修改時(shí)間為“無(wú)”的原因。
| |
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請
點(diǎn)擊舉報。