HTTP詳解-請求、響應、緩存
做過Socket程式設計的人都知道,當我們設計一個通信協定時,“消息頭/消息體”的分割方式是很常用的,消息頭告訴對方這個消息是幹什麼的,消息體告訴對方怎麼幹。HTTP協定傳輸的消息也是這樣規定的,每一個HTTP包都分為HTTP頭和HTTP體兩部分,消息體是可選的,而消息頭是必須的。每當我們打開一個網頁,在上面點選右鍵,選擇“檢視源檔案”,這時看到的HTML代碼就是HTTP的消息體,那麼消息頭可以通過浏覽器的開發工具或者插件可以看到,如果火狐的Firebug,IE的Httpwatch。
用戶端通過發送 HTTP 請求向伺服器請求對資源的通路。 它向伺服器傳遞了一個資料塊,也就是請求資訊,HTTP 請求由三部分組成:請求行、 請求頭和請求正文。
請求行:請求方法 URI 協定/版本
請求頭(Request Header)
請求正文
下面是一個HTTP請求的資料:
請求的第一行是“方法 URL 協定/版本”,并以 回車換行作為結尾。請求行以空格分隔。格式如下:
POST /index.php HTTP/1.1
以上代碼中“GET”代表請求方法,“//ndex.php”表示URI,“HTTP/1.1代表協定和協定的版本。
根據HTTP标準,HTTP請求可以使用多種請求方法。例如:HTTP1.1支援7種請求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。在Internet應用中,最常用的方法是GET和POST。
URL完整地指定了要通路的網絡資源,通常隻要給出相對于伺服器的根目錄的相對目錄即可,是以總是以“/”開頭,最後,協定版本聲明了通信過程中使用HTTP的版本。
在 HTTP 協定中,HTTP 請求可以使用多種請求方法,這些方法指明了要以何種方式來通路 Request-URI 所辨別的資源。HTTP1.1 支援的請求方法如下表所示:
HTTP1.1 中的請求方式:
方法
作用
GET
請求擷取由 Request-URI 所辨別的資源
POST
請求伺服器接收在請求中封裝的實體,并将其作為由 Request-Line 中的 Request-URI 所辨別的資源的一部分
HEAD
請求擷取由 Request-URI 所辨別的資源的響應消息報頭
PUT
請求伺服器存儲一個資源,并用 Request-URI 作為其辨別符
DELETE
請求伺服器删除由 Request-URI 所辨別的資源
TRACE
請求伺服器回送到的請求資訊,主要用于測試或診斷
CONNECT
保留将來使用
OPTIONS
請求查詢伺服器的性能,或者查詢與資源相關的選項和需求
重點介紹 GET、POST 和 HEAD 三個方法:
(1)GET
GET 方法用于擷取由 Request-URI 所辨別的資源的資訊,常見的形式是:
GET Request-URI HTTP/1.1
GET方法是預設的HTTP請求方法,例如當我們通過在浏覽器的位址欄中直接輸入網址的方式去通路網頁的時候,浏覽器采用的就是 GET 方法向伺服器擷取資源。
我們可以使用GET方法來送出表單資料,用GET方法送出的表單資料隻經過了簡單的編碼,同時它将作為URL的一部分向伺服器發送,是以,如果使用GET方法來送出表單資料就存在着安全隐患上。例如:
Http://localhost/login.php?username=aa&password=1234
從上面的URL請求中,很容易就可以辯認出表單送出的内容。(?之後的内容)另外由于GET方法送出的資料是作為URL請求的一部分是以送出的資料量不能太大。這是因為浏覽器對url的長度有限制
各種浏覽器也會對url的長度有所限制,下面是幾種常見浏覽器的url長度限制:(機關:字元)
IE : 2803
Firefox:65536
Chrome:8182
Safari:80000
Opera:190000
(2)POST
POST方法是GET方法的一個替代方法,它主要是向Web伺服器送出表單資料,尤其是大批量的資料。 在請求頭資訊結束之後的兩個回車換行之後(實際是空一行),就是表單送出的資料。如上面提到的post表單資料:
username=aa&password=1234
POST方法克服了GET方法的一些缺點。通過POST方法送出表單資料時,資料不是作為URL請求的一部分而是作為标準資料傳送給Web伺服器,這就克服了GET方法中的資訊無法保密和資料量太小的缺點。是以,出于安全的考慮以及對使用者隐私的尊重,通常表單送出時采用POST方法。
從程式設計的角度來講,如果使用者通過GET方法送出資料,則資料存放在QUERY_STRING環境變量中,而POST方法送出的資料則可以從标準輸入流中擷取。
GET與POST方法有以下差別:
1、 在用戶端,Get方式在通過URL送出資料,資料在URL中可以看到;POST方式,資料放在HTTP包的body中。
2、 GET方式送出的資料大小有限制(因為浏覽器對URL的長度有限制),而POST則沒有此限制。
3、安全性問題。正如在(1)中提到,使用 Get 的時候,參數會顯示在位址欄上,而 Post 不會。是以,如果這些資料是中文資料而且是非敏感資料,那麼使用 get;如果使用者輸入的資料不是中文字元而且包含敏感資料,那麼還是使用 post為好。
4.、伺服器取值方式不一樣。GET方式取值,如php可以使用$_GET來取得變量的值,而POST方式通過$_POST來擷取變量的值。
(3)HEAD
HEAD 方法與 GET 方法幾乎是相同的,它們的差別在于 HEAD 方法隻是請求消息報頭,而不是完整的内容。對于 HEAD 請求的回應部分來說,它的 HTTP 頭部中包含的資訊與通過 GET 請求所得到的資訊是相同的。利用這個方法,不必傳輸整個資源内容,就可以得到 Request-URI 所辨別的資源的資訊。這個方法通常被用于測試超連結的有效性,是否可以通路,以及最近是否更新。
要注意的是,在 HTML 文檔中,書寫 get 和 post,大小寫都可以,但在 HTTP 協定中的 GET 和 POST 隻能是大寫形式。
每個頭域由一個域名,冒号(:)和域值三部分組成。域名是大小寫無關的,域值前可以添加任何數量的空格符,頭域可以被擴充為多行,在每行開始處,使用至少一個空格或制表符。
HTTP最常見的請求頭如下:
Connection: 作用:表示是否需要持久連接配接。 如果伺服器看到這裡的值為“Keep-Alive”,或者看到請求使用的是HTTP 1.1(HTTP 1.1預設進行持久連接配接),它就可以利用持久連接配接的優點,當頁面包含多個元素時(例如Applet,圖檔),顯著地減少下載下傳所需要的時間。要實作這一點,伺服器需要在應答中發送一個Content-Length頭,最簡單的實作方法是:先把内容寫入 ByteArrayOutputStream,然後在正式寫出内容之前計算它的大小; 例如: Connection: keep-alive 當一個網頁打開完成後,用戶端和伺服器之間用于傳輸HTTP資料的TCP連接配接不會關閉,如果用戶端再次通路這個伺服器上的 網頁,會繼續使用這一條已經建立的連接配接 例如: Connection: close 代表一個Request完成後,用戶端和伺服器之間用于傳輸HTTP資料的TCP連接配接會關閉, 當用戶端再次發送Request,需要重建立立TCP連接配接。 Host(發送請求時,該報頭域是必需的) Host請求報頭域主要用于指定被請求資源的Internet主機和端口号,它通常從HTTP URL中提取出來的。 eg:http://;localhost/index.html 浏覽器發送的請求消息中,就會包含Host請求報頭域,如下: Host:localhost 此處使用預設端口号80,若指定了端口号8080,則變成:Host:localhost:8080
Accept: 作用:浏覽器可以接受的媒體類型(MIME類型), 例如: Accept: text/html 代表浏覽器可以接受伺服器回發的類型為 text/html 也就是我們常說的html文檔, 如果伺服器無法傳回text/html類型的資料,伺服器應該傳回一個406錯誤(non acceptable)。 通配符 * 代表任意類型。例如 Accept: */* 代表浏覽器可以處理所有類型,(一般浏覽器發給伺服器都是發這個) Accept-Encoding: 作用: 浏覽器申明自己接收的編碼方法,通常指定壓縮方法,是否支援壓縮,支援什麼壓縮方法(gzip,deflate),(注意:這不是隻字元編碼); 例如: Accept-Encoding: gzip, deflate。Server能夠向支援gzip/deflate的浏覽器傳回經gzip或者deflate編碼的HTML頁面。 許多情形下這可以減少5到10倍的下載下傳時間,也節省帶寬。 Accept-Language: 作用: 浏覽器申明自己接收的語言。 語言跟字元集的差別:中文是語言,中文有多種字元集,比如big5,gb2312,gbk等等; 例如: Accept-Language:zh-cn 。如果請求消息中沒有設定這個報頭域,伺服器假定用戶端對各種語言都可以接受。 User-Agent: 作用:告訴HTTP伺服器, 用戶端使用的作業系統和浏覽器的名稱和版本. 我們上網登陸論壇的時候,往往會看到一些歡迎資訊,其中列出了你的作業系統的名稱和版本,你所使用的浏覽器的名稱和版本,這往往讓很多人感到很神奇,實際上, 伺服器應用程式就是從User-Agent這個請求報頭域中擷取到這些資訊User-Agent請求報頭域允許用戶端将它的作業系統、浏覽器和其它屬性告訴伺服器。 例如: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; InfoPath.2; .NET4.0E) Accept-Charset: 作用:浏覽器申明自己接收的字元集,這就是本文前面介紹的各種字元集和字元編碼,如gb2312,utf-8(通常我們說Charset包括了相應的字元編碼方案); 例如:Accept-Charset:iso-8859-1,gb2312.如果在請求消息中沒有設定這個域,預設是任何字元集都可以接受。 Authorization:授權資訊,通常出現在對伺服器發送的WWW-Authenticate頭的應答中; Authorization請求報頭域主要用于證明用戶端有權檢視某個資源。當浏覽器通路一個頁面時,如果收到伺服器的響應代碼為401(未授權),可以發送一個包含Authorization請求報頭域的請求,要求伺服器對其進行驗證。
Cookie: 作用: 最重要的header, 将cookie的值發送給HTTP 伺服器
Content-Length 作用:發送給HTTP伺服器資料的長度。即請求消息正文的長度; 例如: Content-Length: 38 Content-Type: 作用: 例如:Content-Type: application/x-www-form-urlencoded
Referer: 作用: 提供了Request的上下文資訊的伺服器,告訴伺服器我是從哪個連結過來的,比如從我首頁上連結到一個朋友那裡, 他的伺服器就能夠從HTTP Referer中統計出每天有多少使用者點選我首頁上的連結通路 他的網站。 例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT
If-Modified-Since: 作用: 把浏覽器端緩存頁面的最後修改時間發送到伺服器去,伺服器會把這個時間與伺服器上實際檔案的最後修改時間進行對比。如果時間一緻,那麼傳回304,用戶端就直接使用本地緩存檔案。如果時間不一緻,就會傳回200和新的檔案内容。用戶端接到之後,會丢棄舊檔案,把新檔案緩存起來,并顯示在浏覽器中。 例如:If-Modified-Since: Thu, 09 Feb 2012 09:07:57 GMT。 If-None-Match: 作用: If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETag資訊。 當使用者再次請求該資源時,将在HTTP Request 中加入If-None-Match資訊(ETag的值)。如果伺服器驗證資源的ETag沒有改變(該資源沒有更新),将傳回一個304狀态告訴用戶端使用本地緩存檔案。否則将傳回200狀态和新的資源和Etag. 使用這樣的機制将提高網站的性能 例如: If-None-Match: "03f2b33c0bfcc1:0" Pragma: 作用: 防止頁面被緩存, 在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一樣 Pargma隻有一個用法, 例如: Pragma: no-cache 注意: 在HTTP/1.0版本中,隻實作了Pragema:no-cache, 沒有實作Cache-Control Cache-Control: 作用: 這個是非常重要的規則。 這個用來指定Response-Request遵循的緩存機制。各個指令含義如下 Cache-Control:Public 可以被任何緩存所緩存() Cache-Control:Private 内容隻緩存到私有緩存中 Cache-Control:no-cache 所有内容都不會被緩存
在接收和解釋請求消息後,伺服器會傳回一個 HTTP 響應消息。與 HTTP 請求類似,HTTP 響應也是由三個部分組成,分别是:狀态行、消息報頭和響應正文。如:
HTTP/1.1 200 OK Date: Sun, 17 Mar 2013 08:12:54 GMT Server: Apache/2.2.8 (Win32) PHP/5.2.5 X-Powered-By: PHP/5.2.5 Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 4393 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html; charset=utf-8
<html> <head> <title>HTTP響應示例<title> </head> <body> Hello HTTP! </body> </html>
狀态行由協定版本、數字形式的狀态代碼,及相應的狀态描述組成,各元素之間以空格分隔,結尾時回車換行符,格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
HTTP-Version 表示伺服器 HTTP 協定的版本,Status-Code 表示伺服器發回的響應代碼,Reason-Phrase 表示狀态代碼的文本描述,CRLF 表示回車換行。例如:
HTTP/1.1 200 OK (CRLF)
狀态代碼與狀态描述
狀态代碼由 3 位數字組成, 表示請求是否被了解或被滿足,狀态描述給出了關于狀态碼的簡短的文字描述。狀态碼的第一個數字定義了響應類别,後面兩位數字沒有具體分類。第一個數字有 5 種取值,如下所示。
1xx:訓示資訊——表示請求已經接受,繼續處理
2xx:成功——表示請求已經被成功接收、了解、接受。
3xx:重定向——要完成請求必須進行更進一步的操作
4xx:用戶端錯誤——用戶端請求有錯誤或請求無法實作
5xx:伺服器端錯誤——伺服器未能實作合法的請求。
常見狀态代碼、狀态描述、說明:
200 OK //用戶端請求成功
303:重定向,即從原url重定向到新的url。 例如php 的hear函數header("localtion:/index.php")
400 Bad Request //用戶端請求有文法錯誤,不能被伺服器所了解
401 Unauthorized //請求未經授權,這個狀态代碼必須和WWW-Authenticate報頭域一起使用
403 Forbidden //伺服器收到請求,但是拒絕提供服務,一般是伺服器路徑沒有權限或者是其他權限相關問題
404 Not Found //請求資源不存在,eg:輸入了錯誤的URL
500 Internal Server Error //伺服器發生不可預期的錯誤:一般來說,這個問題都會在伺服器端的源代碼出現錯誤時出現,比如出現死循環。
502 Bad Gateway//作為網關或者代理工作的伺服器嘗試執行請求時,從上遊伺服器接收到無效的響應。比如LNMP ,php-fpm沒有啟動就會報502錯誤。
503 Server Unavailable //伺服器目前不能處理用戶端的請求,一段時間後可能恢複正常,比如java 容器部署war的時候,就出現503,
或者是nginx處理的檔案沒有權限。
504 Gateway Time-out:作為網關或者代理工作的伺服器嘗試執行請求時,未能及時從上遊伺服器(URI辨別出的伺服器,例如HTTP、FTP、LDAP)或者輔助伺服器(例如DNS)收到響應,比如nginx和php-fpm, php設定sleep(200),就會收到504 Gateway Time-out。注意:某些代理伺服器在DNS查詢逾時時會傳回400或者500錯誤
響應正文就是伺服器傳回的資源的内容,響應頭和正文之間也必須用空行分隔。如:
<html>
<head>
<title>HTTP響應示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>
HTTP最常見的響應頭如下所示:
Date: 作用:生成消息的具體時間和日期,即目前的GMT時間。 例如: Date: Sun, 17 Mar 2013 08:12:54 GMT Expires: 作用: 浏覽器會在指定過期時間内使用本地緩存,指明應該在什麼時候認為文檔已經過期,進而不再緩存它。 例如: Expires: Thu, 19 Nov 1981 08:52:00 GMT Vary 例如: Vary: Accept-Encoding
P3P 作用: 用于跨域設定Cookie, 這樣可以解決iframe跨域通路cookie的問題 例如: P3P: CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR Set-Cookie 作用: 非常重要的header, 用于把cookie 發送到用戶端浏覽器, 每一個寫入cookie都會生成一個Set-Cookie. 例如: Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
實體内容的屬性,包括實體資訊類型,長度,壓縮方法,最後一次修改時間,資料有效性等。
ETag: 作用: 和If-None-Match 配合使用。 (執行個體請看上節中If-None-Match的執行個體) 例如: ETag: "03f2b33c0bfcc1:0" Last-Modified: 作用: 用于訓示資源的最後修改日期和時間。(執行個體請看上節的If-Modified-Since的執行個體) 例如: Last-Modified: Wed, 21 Dec 2011 09:09:10 GMT 作用:WEB伺服器告訴浏覽器自己響應的對象的類型和字元集, 例如: Content-Type: text/html; charset=utf-8 Content-Type:text/html;charset=GB2312 Content-Type: image/jpeg Content-Length: 指明實體正文的長度,以位元組方式存儲的十進制數字來表示。在資料下行的過程中,Content-Length的方式要預先在伺服器中緩存所有資料,然後所有資料再一股腦兒地發給用戶端。 例如: Content-Length: 19847 Content-Encoding: 作用:文檔的編碼(Encode)方法。一般是壓縮方式。 WEB伺服器表明自己使用了什麼壓縮方法(gzip,deflate)壓縮響應中的對象。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載下傳時間。 例如:Content-Encoding:gzip Content-Language: 作用: WEB伺服器告訴浏覽器自己響應的對象的語言者 例如: Content-Language:da
Server: 作用:指明HTTP伺服器的軟體資訊 例如:Apache/2.2.8 (Win32) PHP/5.2.5 X-Powered-By: 作用:表示網站是用什麼技術開發的 例如: X-Powered-By: PHP/5.2.5
例如: Connection: keep-alive 當一個網頁打開完成後,用戶端和伺服器之間用于傳輸HTTP資料的TCP連接配接不會關閉,如果用戶端再次通路這個伺服器上的網頁,會繼續使用這一條已經建立的連接配接 例如: Connection: close 代表一個Request完成後,用戶端和伺服器之間用于傳輸HTTP資料的TCP連接配接會關閉, 當用戶端再次發送Request,需要重建立立TCP連接配接。
Location: 作用: 用于重定向一個新的位置, 包含新的URL位址 執行個體請看304狀态執行個體
無狀态是指協定對于事務處理沒有記憶能力,伺服器不知道用戶端是什麼狀态。從另一方面講,打開一個伺服器上的網頁和你之前打開這個伺服器上的網頁之間沒有任何聯系。
HTTP是一個無狀态的面向連接配接的協定,無狀态不代表HTTP不能保持TCP連接配接,更不能代表HTTP使用的是UDP協定(無連接配接)。
從HTTP/1.1起,預設都開啟了Keep-Alive,保持連接配接特性,簡單地說,當一個網頁打開完成後,用戶端和伺服器之間用于傳輸HTTP資料的TCP連接配接不會關閉,如果用戶端再次通路這個伺服器上的網頁,會繼續使用這一條已經建立的連接配接。
Keep-Alive不會永久保持連接配接,它有一個保持時間,可以在不同的伺服器軟體(如Apache)中設定這個時間。
浏覽器緩存:包括頁面html緩存和圖檔js,css等資源的緩存。如下圖,浏覽器緩存是基于把頁面資訊儲存到使用者本地電腦硬碟裡。
1)伺服器響應更快:因為請求從緩存伺服器(離用戶端更近)而不是源伺服器被相應,這個過程耗時更少,讓伺服器看上去響應更快。
2)減少網絡帶寬消耗:當副本被重用時會減低用戶端的帶寬消耗;客戶可以節省帶寬費用,控制帶寬的需求的增長并更易于管理。
頁面緩存狀态是由http header決定的,一個浏覽器請求資訊,一個是伺服器響應資訊。主要包括Pragma: no-cache、Cache-Control、 Expires、 Last-Modified、If-Modified-Since。其中Pragma: no-cache由HTTP/1.0規定,Cache-Control由HTTP/1.1規定。
工作原理圖:
從圖中我們可以看到原理主要分三步:
第一次請求:浏覽器通過http的header報頭,附帶Expires,Cache-Control,Last-Modified/Etag向伺服器請求,此時伺服器記錄第一次請求的Last-Modified/Etag
再次請求:當浏覽器再次請求的時候,請求頭附帶Expires,Cache-Control,If-Modified-Since/Etag向伺服器請求
伺服器根據第一次記錄的Last-Modified/Etag和再次請求的If-Modified-Since/Etag做對比,判斷是否需要更新,伺服器通過這兩個頭判斷本地資源未發生變化,客 戶端不需要重新下載下傳,傳回304響應。常見流程如下圖所示:
Expires:設定頁面過期時間,格林威治時間GMT
Cache-Control:更細緻的控制緩存的内容
Last-Modified:請求對象最後一次的修改時間 用來判斷緩存是否過期 通常由檔案的時間資訊産生
ETag:響應中資源的校驗值,在伺服器上某個時段是唯一辨別的。ETag是一個可以 與Web資源關聯的記号(token),和Last-Modified功能才不多,也是一個辨別符,一般和Last-Modified一起使用,加強伺服器判斷的準确度。
Date:伺服器的時間
If-Modified-Since:用戶端存取的該資源最後一次修改的時間,用來和伺服器端的Last-Modified做比較
If-None-Match:用戶端存取的該資源的檢驗值,同ETag。
Cache-Control的主要參數
Cache-Control: private/public Public 響應會被緩存,并且在多使用者間共享。 Private 響應隻能夠作為私有的緩存,不能再使用者間共享。
Cache-Control: no-cache:不進行緩存
Cache-Control: max-age=x:緩存時間 以秒為機關
Cache-Control: must-revalidate:如果頁面是過期的 則去伺服器進行擷取。
我們nginx測試:
server {
listen 8081;
server_name 10.163.1.175;
if ($host != 'www.test1.com' ) {
#rewrite ^/(.*)$ http://www.test1.com/$1 permanent;
}
index index.html index.htm index.php;
root /home/www/app/;
access_log /mnt/app/nginx/logs/test1.home.log main;
location ~ .*\.zip?$
{
access_log off;
location ~ .*\.txt?$ {
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
expires 30d;
location ~ .*\.(js|css|zip)?$
expires 12h;
if (!-e $request_filename) {
rewrite ^/(.+)$ /index.php?url=$1 last;
break;
location ~ .*\.(php|php5)?$
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
add_header Content-Type text/html;
然後我們代理兩個域名指向同一個端口:
listen 80;
server_name www.test1.com test1.com;
location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header Access-Control-Allow-Origin *;
proxy_next_upstream http_502 http_504 error timeout invalid_header;
server_name www.test2.com test2.com;
我們通路www.test2.com,直接指向www.test1.com,http是304響應。
當我們把8081端口的配置去掉
重新開機nginx,同一個通路www.test2.com,發現還是直接跳轉到www.test1.com。
這是因為浏覽器304緩存的問題。我們直接使用新浏覽器通路,就直接通路就不會跳轉啦。
這個主要通過伺服器的配置來實作這個技術,如果使用apache伺服器的話,可以使用mod_expires子產品來實作:
編譯mod_expires子產品:
Cd /root/httpd-2.2.3/modules/metadata
/usr/local/apache/bin/apxs -i -a -c mod_expires.c //編譯
編輯httpd.conf配置:添加下面内容
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
ExpiresByType text/html "access plus 1 months"
ExpiresByType text/css "access plus 1 months"
ExpiresByType image/gif "access plus 1 months"
ExpiresByType image/jpeg "access plus 1 months"
ExpiresByType image/jpg "access plus 1 months"
ExpiresByType image/png "access plus 1 months"
EXpiresByType application/x-shockwave-flash "access plus 1 months"
EXpiresByType application/x-javascript "access plus 1 months"
#ExpiresByType video/x-flv "access plus 1 months"
</IfModule>
解釋:第一句--開啟服務
第二句--預設時間是一個月
在下面是關于各種類型的資源的緩存時間設定