主要特點
- 支援 客戶端 與 伺服器端
- 簡單快速: 只需要傳送請求方法(GET、POST、HEAD)與路徑
- HTTP允許傳輸任一類型的數據對象,由Content-Type標記就可以
- 無連接: 限制每次連接只處理一個請求(從客戶請求到收到答應就斷開)。這個特點可以節省傳輸時間。
- 無狀態:對事務處理沒有記憶能力。
HTTP協議與URL
HTTP就是一個客戶端發請求,伺服器端回應的一個協議。基於TPC的連接方式。
http://host[":"port][abs_path]
host: 合法的網路主機域名或IP位址
port: 一個端口號(為空的話則為80)
abs_path: 如果沒有給abs_path,當作為請求URL時,會以/
這個形式給出。
HTTP協議 請求
請求包含三區塊:
- Request Headers/Method/Request Url(包含 請求方式 與 請求的URL和協議版本)
- 指定要請求資料的網路主機或端口號
- Message Body請求的內容
例如:
GET / HTTP/1.1
Host: developer.mozilla.org
Accept-Language: fr
請求方法 request method
- GET : GET方法就是要請求資料,而請求資料時只用GET。
- POST : POST方法是提交內容,通常會造成伺服器端上的一些改變。
- HEAD : HEAD方法是要請求一個回應(與GET相同),不同於GET的是,不需要回應的內容(只需要回應首行)。
- PUT : PUT方法請求伺服器儲存一個資料
- DELETE : 請求刪除一個資料
- TRACE : 追蹤資料,請求伺服器端回送收到的請求訊息。(主要用在診斷或測試)
- CONNECT : 請求針對特定的資料建立一個管道
- OPTIONS : 請求查詢伺服器的性能或查詢特定資料
- PATCH : 修改資料
cache 快取
為什麼需要cache 快取?
cache的用處是為了節省流量、節省時間然後節省資源耗損。
如果今天每一個訪客到首頁都要讓你重新到資料庫抓資料,這樣對資料庫的負擔會很大,假如說這個網站並不是短期之內會有變動的,那就可以使用cache快取(也可以說緩存)。
簡單來說,就是第一次撈資料後,就先把資料存到某個地方,之後如果需要,就可以用極快的方式取到,也不用要重新請求資料庫。
伺服器與瀏覽器間的Cache機制
要達成瀏覽器先把照片Cache起來,可以在HTTP Response Header 裡面加上一個Expires
,裡面就是這個 Cache 到期的時間,例如:
Expires: Sat, 31 Dec 2022 00:00:00 GMT
如果沒有超過這個時間,瀏覽器就不會從後端取資料,而是直接從電腦存好的cache拿。
這個時間是以電腦的時間為基準,所以如果刻意更改時間,讓他超過expires date,瀏覽器就會在發送新的request。
cache-control
為了應對上面的問題,就有了cache control(cache control也不只解決這個問題)。
其中的一個用法就是 max-age
,max-age
和expired
一樣,都是可以用來設定cache過期時間,但是expired
設定到期日期,而max-age
設定從第一次抓資料後,經過多少秒數會過期。
如果同時設定了expired
和max-age
,會看max-age
喔!
如果是機密資料,不想要任何快取呢?
可以使用cache-control: no-store
。
過期之後 ...
cache到期後,有兩條路
- (資料有改變)重新請求資料,伺服器重新給資料
- (資料都沒改變)重新請求資料,伺服器說:資料都一樣,所以可以繼續用原本的快取喔!
要做到這樣的判斷,需要在客戶端第一次抓資料時,伺服器傳回response的Header上加上Last-Modified
,來標示這個檔案最後的更改時間。
等到下一次客戶端要在取資料時,可以再request的header上加上If-Modified-Since
,來告訴伺服器,上次的資料最後修改日期,伺服器就會判斷在這之後有沒有修改,若有就會給客戶新資料,若無,就會回傳Status code: 304 (Not Modified)
。
上面這個方法是用修改日期來看,但是修改的定義,只要將檔案打開再儲存關起來,就算沒改內容也算是修改。
所以有另一個方法是看檔案內容有沒有一樣。
Etag
和 If-None-Match
伺服器第一次傳資料回應時,會帶上Etag
(檔案獨有的),等cache過期,瀏覽器會再發送帶有If-None-Match
的請求,伺服器判斷有沒有相同。
如果不會常常變動資料,但是又希望資料再變動後馬上讓客戶端取到呢?
- 搭配
max-age
和Etag
先設定Cache-Control: max-age=0
,讓客戶一拿到資料,0秒後cache就過期,等客戶再造訪網頁(重整..)後,就會再重抓資料,但是因為同時也有附上Etag
。所以客戶端的請求會帶上If-None-Match
,伺服器就可以判斷是否需要重新傳送。 Cache-control: no-cache
和Cache-control: no-store
不同,
Cache-control: no-store
是永遠不要快存。
Cache-control: no-cache
是永遠檢查快存。
最後還會遇到一個問題,因為現在通常會做SPA架構,透過Webpack打包,只需要引入script就好。
通常index.html的body內部是空的,這樣要怎麼讓客戶端發現內容有更動呢?
將Etag寫入檔案內
解決方法就是,將Etag寫入引入的script名稱(例如:script-123abc.js 下一次更改時改為script-456def.js)
Content-Type
HTTP請求的Content-Type會出現在POST或PUT時,讓客戶端告訴伺服器自己傳的資料是什麼內容類型。
HTTP協議 回應
HTTP/1.1 200 OK
Date: Sat, 09 Oct 2010 14:28:02 GMT
Server: Apache
Last-Modified: Tue, 01 Dec 2009 20:18:22 GMT
ETag: "51142bc1-7449-479b075b2891b"
Accept-Ranges: bytes
Content-Length: 29769
Content-Type: text/html
HTTP 回應狀態碼
- 1XX 訊息類 (收到請求,請求者繼續執行操作)
- 2XX 成功類 (操作被成功接受並處理),例如:200 成功回應
- 3XX 重定向類 (需進一步操作才能完成),例如:301 成功轉向
- 4XX 客戶端錯誤類 (請求語法錯誤或無法完成請求) 例如:404 找不到資源
- 5XX 伺服器錯誤類 (後端的問題),例如:500 伺服器錯誤
Content-Type
在回應中Content-Type 用來表示資源的 media type。
瀏覽器有時會自己推測內容類型(MIME sniffing),如果要阻止這個行為,可以在回應中設定 X-Content-Type-Options 標頭為 nosniff。