Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
HTTP協議(HyperText Transfer Protocol,超文本傳輸協議):是一種發布和接收 HTML頁面的方法。
HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)簡單講是HTTP的安全版,在HTTP下加入SSL層。
SSL(Secure Sockets Layer 安全套接層)主要用于Web的安全傳輸協議,在傳輸層對網絡連接進行加密,保障在Internet上數據傳輸的安全。
HTTP通信由兩部分組成: 客戶端請求消息 與 服務器響應消息
HTTP的請求與響應
瀏覽器發送HTTP請求的過程:
URL(Uniform / Universal Resource Locator的縮寫):統一資源定位符,是用于完整地描述Internet上網頁和其他資源的地址的一種標識方法。
URL
基本格式:scheme://host[:port#]/path/…/[?query-string][#anchor]
例如:
URL只是標識資源的位置,而HTTP是用來提交和獲取資源??蛻舳税l送一個HTTP請求到服務器的請求消息,包括以下格式:
請求行、請求頭部、空行、請求數據
四個部分組成,下圖給出了請求報文的一般格式。
請求報文的一般格式
一個典型的HTTP請求示例:
GET https://www.baidu.com/ HTTP/1.1 Host: www.baidu.com Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Referer: http://www.baidu.com/ Accept-Encoding: gzip, deflate, sdch, br Accept-Language: zh-CN,zh;q=0.8,en;q=0.6 Cookie: BAIDUI......
GET https://www.baidu.com/ HTTP/1.1
根據HTTP標準,HTTP請求可以使用多種請求方法。
HTTP 0.9:只有基本的文本 GET 功能。
HTTP 1.0:完善的請求/響應模型,并將協議補充完整,定義了三種請求方法: GET, POST 和 HEAD方法。
HTTP 1.1:在 1.0 基礎上進行更新,新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
HTTP 2.0(未普及):請求/響應首部的定義基本沒有改變,只是所有首部鍵必須全部小寫,而且請求行要獨立為 :method、:scheme、:host、:path這些鍵值對。
請求方法
HTTP請求主要分為Get和Post兩種方法
注意:避免使用Get方式提交表單,因為有可能會導致安全問題。 比如說在登陸表單中用Get方式,用戶輸入的用戶名和密碼將在地址欄中暴露無遺。
1. Host (主機和端口號)
Host:對應網址URL中的Web名稱和端口號,用于指定被請求資源的Internet主機和端口號,通常屬于URL的一部分。
2. Connection (鏈接類型)
Connection:表示客戶端與服務連接類型
1.Client 發起一個包含 Connection:keep-alive 的請求,HTTP/1.1使用 keep-alive 為默認值。
2.Server收到請求后:
3.如果client收到包含 Connection:keep-alive 的響應,向同一個連接發送下一個請求,直到一方主動關閉連接。
keep-alive在很多情況下能夠重用連接,減少資源消耗,縮短響應時間,比如當瀏覽器需要多個文件時(比如一個HTML文件和相關的圖形文件),不需要每次都去請求建立連接。
3. Upgrade-Insecure-Requests (升級為HTTPS請求)
Upgrade-Insecure-Requests:升級不安全的請求,意思是會在加載 http 資源時自動替換成 https 請求,讓瀏覽器不再顯示https頁面中的http請求警報。
HTTPS 是以安全為目標的 HTTP 通道,所以在 HTTPS 承載的頁面上不允許出現 HTTP 請求,一旦出現就是提示或報錯。
4. User-Agent (瀏覽器名稱)
User-Agent:是客戶瀏覽器的名稱,以后會詳細講。
5. Accept (傳輸文件類型)
Accept:指瀏覽器或其他客戶端可以接受的MIME(Multipurpose Internet Mail Extensions(多用途互聯網郵件擴展))文件類型,服務器可以根據它判斷并返回適當的文件格式。
舉例:
6. Referer (頁面跳轉處)
Referer:表明產生請求的網頁來自于哪個URL,用戶是從該 Referer頁面訪問到當前請求的頁面。這個屬性可以用來跟蹤Web請求來自哪個頁面,是從什么網站來的等。
有時候遇到下載某網站圖片,需要對應的referer,否則無法下載圖片,那是因為人家做了防盜鏈,原理就是根據referer去判斷是否是本網站的地址,如果不是,則拒絕,如果是,就可以下載;
7. Accept-Encoding(文件編解碼格式)
Accept-Encoding:指出瀏覽器可以接受的編碼方式。編碼方式不同于文件格式,它是為了壓縮文件并加速文件傳遞速度。瀏覽器在接收到Web響應之后先解碼,然后再檢查文件格式,許多情形下這可以減少大量的下載時間。
舉例:Accept-Encoding:gzip;q=1.0, identity; q=0.5, *;q=0
如果有多個Encoding同時匹配, 按照q值順序排列,本例中按順序支持 gzip, identity壓縮編碼,支持gzip的瀏覽器會返回經過gzip編碼的HTML頁面。 如果請求消息中沒有設置這個域服務器假定客戶端對各種內容編碼都可以接受。
8. Accept-Language(語言種類)
Accept-Langeuage:指出瀏覽器可以接受的語言種類,如en或en-us指英語,zh或者zh-cn指中文,當服務器能夠提供一種以上的語言版本時要用到。
9. Accept-Charset(字符編碼)
Accept-Charset:指出瀏覽器可以接受的字符編碼。
舉例:Accept-Charset:iso-8859-1,gb2312,utf-8
如果在請求消息中沒有設置這個域,缺省是任何字符集都可以接受。
10. Cookie (Cookie)
Cookie:瀏覽器用這個屬性向服務器發送Cookie。Cookie是在瀏覽器中寄存的小型數據體,它可以記載和服務器相關的用戶信息,也可以用來實現會話功能,以后會詳細講。
11. Content-Type (POST數據類型)
Content-Type:POST請求里用來表示的內容類型。
舉例:Content-Type=Text/XML; charset=gb2312:
指明該請求的消息體中包含的是純文本的XML類型的數據,字符編碼采用“gb2312”。
HTTP響應也由四個部分組成,分別是: 狀態行、消息報頭、空行、響應正文
HTTP響應
HTTP/1.1 200 OK Server: Tengine Connection: keep-alive Date: Wed, 30 Nov 2016 07:58:21 GMT Cache-Control: no-cache Content-Type: text/html;charset=UTF-8 Keep-Alive: timeout=20 Vary: Accept-Encoding Pragma: no-cache X-NWS-LOG-UUID: bd27210a-24e5-4740-8f6c-25dbafa9c395 Content-Length: 180945 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ....
理論上所有的響應頭信息都應該是回應請求頭的。但是服務端為了效率,安全,還有其他方面的考慮,會添加相對應的響應頭信息,從上圖可以看到:
1. Cache-Control:must-revalidate, no-cache, private。
這個值告訴客戶端,服務端不希望客戶端緩存資源,在下次請求資源時,必須要從新請求服務器,不能從緩存副本中獲取資源。
2. Connection:keep-alive
這個字段作為回應客戶端的Connection:keep-alive,告訴客戶端服務器的tcp連接也是一個長連接,客戶端可以繼續使用這個tcp連接發送http請求。
3. Content-Encoding:gzip
告訴客戶端,服務端發送的資源是采用gzip編碼的,客戶端看到這個信息后,應該采用gzip對資源進行解碼。
4. Content-Type:text/html;charset=UTF-8
告訴客戶端,資源文件的類型,還有字符編碼,客戶端通過utf-8對資源進行解碼,然后對資源進行html解析。通常我們會看到有些網站是亂碼的,往往就是服務器端沒有返回正確的編碼。
5. Date:Sun, 21 Sep 2016 06:18:21 GMT
這個是服務端發送資源時的服務器時間,GMT是格林尼治所在地的標準時間。http協議中發送的時間都是GMT的,這主要是解決在互聯網上,不同時區在相互請求資源的時候,時間混亂問題。
6. Expires:Sun, 1 Jan 2000 01:00:00 GMT
這個響應頭也是跟緩存有關的,告訴客戶端在這個時間前,可以直接訪問緩存副本,很顯然這個值會存在問題,因為客戶端和服務器的時間不一定會都是相同的,如果時間不同就會導致問題。所以這個響應頭是沒有Cache-Control:max-age=*這個響應頭準確的,因為max-age=date中的date是個相對時間,不僅更好理解,也更準確。
7. Pragma:no-cache
這個含義與Cache-Control等同。
8.Server:Tengine/1.4.6
這個是服務器和相對應的版本,只是告訴客戶端服務器的信息。
9. Transfer-Encoding:chunked
這個響應頭告訴客戶端,服務器發送的資源的方式是分塊發送的。一般分塊發送的資源都是服務器動態生成的,在發送時還不知道發送資源的大小,所以采用分塊發送,每一塊都是獨立的,獨立的塊都能標示自己的長度,最后一塊是0長度的,當客戶端讀到這個0長度的塊時,就可以確定資源已經傳輸完了。
10. Vary: Accept-Encoding
告訴緩存服務器,緩存壓縮文件和非壓縮文件兩個版本,現在這個字段用處并不大,因為現在的瀏覽器都是支持壓縮的。
Cookie 和 Session:
服務器和客戶端的交互僅限于請求/響應過程,結束之后便斷開,在下一次請求時,服務器會認為新的客戶端。
為了維護他們之間的鏈接,讓服務器知道這是前一個用戶發送的請求,必須在一個地方保存客戶端的信息。
響應狀態碼
響應狀態代碼有三位數字組成,第一個數字定義了響應的類別,且有五種可能取值。
常見狀態碼:
前面幾篇教程我們了解了如何在 Go 語言中解析用戶請求信息,包括表單字段和文件上傳,接下來,我們來看看處理完請求后,如何將響應發送給客戶端。HTTP 響應的報文結構如下所示:
HTTP 響應報文結構
和 HTTP 請求報文結構類似,響應報文也可以分為三部分:狀態行、響應頭(首部字段)和響應主體。
首先是狀態行,在狀態行中包含了 HTTP 協議版本和響應狀態碼,200 OK 表示響應成功,更多狀態碼信息(常見的有 404、403、500、301 等)可以網上查看下 HTTP 協議或者閱讀 HTTP 響應狀態碼這篇文章了解。
然后是響應頭,其中包含了 HTTP 響應的首部字段,比如內容類型/編碼、緩存控制、Cookie 信息等。
最后是響應實體,對于 API 接口來說,通常就是返回的 XML/JSON 格式數據,對于 HTML 視圖響應,就是一個標準的 HTML 文檔,如上圖所示。響應頭和響應報文之間通過兩個換行符分隔。
在 Go 語言中,客戶端請求信息都封裝到了 Request 對象,但是發送給客戶端的響應并不是 Response 對象,而是 ResponseWriter:
func Home(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Welcome to my blog site")
}
ResponseWriter 是處理器用來創建 HTTP 響應的接口,其源碼結構如下所示:
type ResponseWriter interface {
// 用于設置/獲取所有響應頭信息
Header() Header
// 用于寫入數據到響應實體
Write([]byte) (int, error)
// 用于設置響應狀態碼
WriteHeader(statusCode int)
}
實際上,在底層支撐 ResponseWriter 的結構體就是 http.response,詳見 net/http 包下 server.go 中的 readRequest 方法(調用處理器處理 HTTP 請求時調用了該方法返回響應對象),并且其返回值是 response 指針,這也是為什么在處理器方法聲明的時候 Request 是指針類型,而 ResponseWriter 不是,實際上在底層,響應對象也是指針類型(因為在應用代碼中需要設置響應頭和響應實體,所以響應對象理應是指針類型):
func (c *conn) readRequest(ctx context.Context) (w *response, err error) {
...
w = &response{
conn: c,
cancelCtx: cancelCtx,
req: req,
reqBody: req.Body,
handlerHeader: make(Header),
contentLength: -1,
closeNotifyCh: make(chan bool, 1),
wants10KeepAlive: req.wantsHttp10KeepAlive(),
wantsClose: req.wantsClose(),
}
if isH2Upgrade {
w.closeAfterReply = true
}
w.cw.res = w
w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize)
return w, nil
}
response 結構體定義和 ResponseWriter 一樣都位于 server.go,感興趣的同學可以去看下源碼,不過由于 response 對外不可見,所以只能通過 ResponseWriter 接口訪問它。兩者之間的關系是 ResponseWriter 是一個接口,而 http.response 實現了它。當我們引用 ResponseWriter 時,實際上引用的是 http.response 對象實例。
如上面的 ResponseWriter 接口定義源碼所示,它包含三個方法:
WriteHeader 這個方法名有點誤導,其實它并不是用來設置響應頭的,該方法支持傳入一個整型數據用來表示響應狀態碼,如果不調用該方法的話,默認響應狀態碼是 200 OK。
WriteHeader 的主要作用是在 API 接口中返回錯誤碼,我們在 goblog/handlers/common.go 中新增一個處理器方法 Error,并通過 w.WriteHeader 返回一個 401 未認證狀態碼(注意在運行時 w 代表的是對應的 response 對象實例,而不是接口):
func Error(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(401)
fmt.Fprintln(w, "認證后才能訪問該接口")
}
注:這里通過 fmt.Fprintln 將文本字符串寫入響應對象。
然后在 routes/web.go 中添加一個路由與之映射:
WebRoute{
"ApiError",
"GET",
"/error",
handlers.Error,
},
重啟 HTTP 服務器,通過 curl 訪問 http://localhost:8080/error,返回的完整響應報文如下:
可以看到響應狀態碼是 401 Unauthorized,表示該接口需要認證后才能訪問。這里,我們在運行 curl 時帶上 -i 選項,以便可以看到完整的響應報文,第一行是響應狀態行,然后是響應頭信息,響應頭每一行是一個鍵值對映射,通過冒號分隔,左側是字段名,右側是字段值,最后是響應實體,也就是我們在代碼中寫入的響應數據,響應實體和響應頭之間通過一個空行分隔(兩個換行符)。
Header 方法用于設置響應頭信息,我們可以通過 w.Header().Set 方法設置響應頭(w.Header() 方法返回的是 Header 響應頭對象,它和請求頭共用一個結構體,因此請求頭上支持的方法這里都支持,比如可以通過 w.Header().Add 方法新增響應頭),這里我們設置一個 301 重定向響應,只需要通過 w.WriteHeader 方法將響應狀態碼設置為 301,再通過 w.Header().Set 方法將負責重定向的響應頭 Location 設置為一個可訪問域名即可。
在 goblog/handlers/common.go 中新建一個處理器方法 Redirect,在其中編寫重定向實現代碼如下:
func Redirect(w http.ResponseWriter, r *http.Request) {
// 設置一個 301 重定向
w.Header().Set("Location", "https://xueyuanjun.com")
w.WriteHeader(301)
}
對于重定向請求,無需設置響應實體,另外需要注意的是 w.Header().Set 必須在 w.WriteHeader 之前調用,因為一旦調用 w.WriteHeader 之后,就不能對響應頭進行設置了。
接下來,在 routes/web.go 中注冊對應的重定向路由:
WebRoute{
"Redirect",
"GET",
"/redirect",
handlers.Redirect,
},
重啟 HTTP 服務器,通過 curl 訪問該路由可以清楚看到響應被重定向,并且響應實體為空:
如果是在瀏覽器中訪問的話,頁面就會跳轉到 https://xueyuanjun.com:
Write 方法用于寫入數據到 HTTP 響應實體,如果調用 Write 方法時還不知道 Content-Type,會通過數據的前 512 個字節進行判斷。
以 goblog/handlers/common.go 中定義的 Home 處理器方法為例,我們可以通過 w.Write 寫入一段歡迎文本到響應實體:
func Home(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("歡迎訪問學院君個人網站"));
}
由于 Write 方法接受的參數類型是 []byte 切片,所以需要將字符串轉換為字節切片類型。啟動 HTTP 服務器,通過 curl 訪問首頁,就可以看到返回的文本信息了:
如果要返回 HTML 文檔,可以這么寫入響應數據:
func Home(w http.ResponseWriter, r *http.Request) {
//w.Write([]byte("歡迎訪問學院君個人網站"));
html := `<html>
<head>
<title>學院君個人網站</title>
</head>
<body>
<h1>歡迎訪問學院君個人網站</h1>
</body>
</html>`
w.Write([]byte(html))
}
當然,后面介紹視圖模板后,可以通過視圖模板渲染 HTML 文檔,這里我們先通過一個簡單的包含 HTML 文檔信息的字符串替代,重啟 HTTP 服務器,通過瀏覽器訪問,就可以看到對應的 HTML 視圖了:
此外,由于響應數據的內容類型變成了 HTML,在響應頭中,也可以看到 Content-Type 也自動調整成了 text/html,不再是純文本格式。這里的 Content-Type 就是根據傳入的數據自行判斷出來的。
當然,我們也可以返回 JSON 格式數據:
type Greeting struct {
Message string `json:"message"`
}
func Home(w http.ResponseWriter, r *http.Request) {
// 返回文本字符串
//w.Write([]byte("歡迎訪問學院君個人網站"));
// 返回 HTML 文檔
/*html := `<html>
<head>
<title>學院君個人網站</title>
</head>
<body>
<h1>歡迎訪問學院君個人網站</h1>
</body>
</html>`
w.Write([]byte(html))*/
// 返回 JSON 格式數據
greeting := Greeting{
"歡迎訪問學院君個人網站",
}
message, _ := json.Marshal(greeting)
w.Write(message)
}
重啟 HTTP 服務器,在瀏覽器中訪問 http://localhost:8080:
雖然返回的確實是合法的 JSON 格式數據,但是內容類型依然是 text/plain,而不是 application/json,要返回這個格式的響應頭,需要設置響應頭才能實現:
// 返回 JSON 格式數據
greeting := Greeting{
"歡迎訪問學院君個人網站",
}
message, _ := json.Marshal(greeting)
w.Header().Set("Content-Type", "application/json")
w.Write(message)
重啟 HTTP 服務器,并再次通過 curl 訪問首頁,就可以看到內容類型變成 application/json 了:
(全文完)
. HTTP請求格式
做過Socket編程的人都知道,當我們設計一個通信協議時,“消息頭/消息體”的分割方式是很常用的,消息頭告訴對方這個消息是干什么的,消息體告訴對 方怎么干。HTTP協議傳輸的消息也是這樣規定的,每一個HTTP包都分為HTTP頭和HTTP體兩部分,消息體是可選的,而消息頭是必須的。每當我們打 開一個網頁,在上面點擊右鍵,選擇“查看源文件”,這時看到的HTML代碼就是HTTP的消息體,那么消息頭可以通過瀏覽器的開發工具或者插件可以看到, 如果火狐的Firebug,IE的Httpwatch。
客戶端通過發送 HTTP 請求向服務器請求對資源的訪問。 它向服務器傳遞了一個數據塊,也就是請求信息,HTTP 請求由三部分組成:請求行、 請求頭和請求正文。
請求行:請求方法 URI 協議/版本
請求頭(Request Header)
請求正文
下面是一個HTTP請求的數據:
POST /index.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/
Content-Length:25
Content-Type:application/x-www-form-urlencoded
username=aa&password=1234
1、請求行:請求方法URI協議/版本
請求的第一行是“方法 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 只能是大寫形式。
2. 請求頭
每個頭域由一個域名,冒號(:)和域值三部分組成。域名是大小寫無關的,域值前可以添加任何數量的空格符,頭域可以被擴展為多行,在每行開始處,使用至少一個空格或制表符。
HTTP最常見的請求頭如下:
Transport 頭域
Connection:
作用:表示是否需要持久連接。
如果服務器看到這里的值為“Keep-Alive”,或者看到請求使用的是HTTP 1.1(HTTP 1.1默認進行持久連接),它就可以利用持久連接的優點,當頁面包含多個元素時(例如Applet,圖片),顯著地減少下載所需要的時間。要實現這一點,服務器需要在應答中發送一個Content-Length頭,最簡單的實現方法是:先把內容寫入 ByteArrayOutputStream,然后在正式寫出內容之前計算它的大?。?/p>
例如: 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
Client 頭域
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/Login 頭域
Cookie:
作用: 最重要的header, 將cookie的值發送給HTTP 服務器
Entity頭域
Content-Length
作用:發送給HTTP服務器數據的長度。即請求消息正文的長度;
例如: Content-Length: 38
Content-Type:
作用:
例如:Content-Type: application/x-www-form-urlencoded
Miscellaneous 頭域
Referer:
作用: 提供了Request的上下文信息的服務器,告訴服務器我是從哪個鏈接過來的,比如從我主頁上鏈接到一個朋友那里, 他的服務器就能夠從HTTP Referer中統計出每天有多少用戶點擊我主頁上的鏈接訪問 他的網站。
例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT
Cache 頭域
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 所有內容都不會被緩存
2. HTTP響應格式
在接收和解釋請求消息后,服務器會返回一個 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>
1、狀態行
狀態行由協議版本、數字形式的狀態代碼,及相應的狀態描述組成,各元素之間以空格分隔,結尾時回車換行符,格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
HTTP-Version 表示服務器 HTTP 協議的版本,Status-Code 表示服務器發回的響應代碼,Reason-Phrase 表示狀態代碼的文本描述,CRLF 表示回車換行。例如:
HTTP/1.1 200 OK (CRLF)
狀態代碼與狀態描述
狀態代碼由 3 位數字組成, 表示請求是否被理解或被滿足,狀態描述給出了關于狀態碼的簡短的文字描述。狀態碼的第一個數字定義了響應類別,后面兩位數字沒有具體分類。第一個數字有 5 種取值,如下所示。
常見狀態代碼、狀態描述、說明:
200 OK //客戶端請求成功
400 Bad Request //客戶端請求有語法錯誤,不能被服務器所理解
401 Unauthorized //請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用
403 Forbidden //服務器收到請求,但是拒絕提供服務
404 Not Found //請求資源不存在,eg:輸入了錯誤的URL
500 Internal Server Error //服務器發生不可預期的錯誤
503 Server Unavailable //服務器當前不能處理客戶端的請求,一段時間后可能恢復正常
2、響應正文
響應正文就是服務器返回的資源的內容,響應頭和正文之間也必須用空行分隔。如:
3 、響應頭信息
HTTP最常見的響應頭如下所示:
Cache頭域
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
Cookie/Login 頭域
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=/
Entity實體頭域:
實體內容的屬性,包括實體信息類型,長度,壓縮方法,最后一次修改時間,數據有效性等。
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
Content-Type:
作用: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
Miscellaneous 頭域
Server:
作用:指明HTTP服務器的軟件信息
例如:Apache/2.2.8 (Win32) PHP/5.2.5
X-Powered-By:
作用:表示網站是用什么技術開發的
例如: X-Powered-By: PHP/5.2.5
Transport頭域
Connection:
例如: Connection: keep-alive 當一個網頁打開完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接
例如: Connection: close 代表一個Request完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接會關閉, 當客戶端再次發送Request,需要重新建立TCP連接。
Location頭域
Location:
作用: 用于重定向一個新的位置, 包含新的URL地址
實例請看304狀態實例
HTTP協議是無狀態的和Connection: keep-alive的區別
無狀態是指協議對于事務處理沒有記憶能力,服務器不知道客戶端是什么狀態。從另一方面講,打開一個服務器上的網頁和你之前打開這個服務器上的網頁之間沒有任何聯系。
HTTP是一個無狀態的面向連接的協議,無狀態不代表HTTP不能保持TCP連接,更不能代表HTTP使用的是UDP協議(無連接)。
從HTTP/1.1起,默認都開啟了Keep-Alive,保持連接特性,簡單地說,當一個網頁打開完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接。
Keep-Alive不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如Apache)中設定這個時間。
3. 瀏覽器緩存
瀏覽器緩存:包括頁面html緩存和圖片js,css等資源的緩存。如下圖,瀏覽器緩存是基于把頁面信息保存到用戶本地電腦硬盤里。
1、緩存的優點:
1)服務器響應更快:因為請求從緩存服務器(離客戶端更近)而不是源服務器被相應,這個過程耗時更少,讓服務器看上去響應更快。
2)減少網絡帶寬消耗:當副本被重用時會減低客戶端的帶寬消耗;客戶可以節省帶寬費用,控制帶寬的需求的增長并更易于管理。
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擴展消息頭
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:如果頁面是過期的 則去服務器進行獲取。
2、關于圖片,css,js,flash的緩存
這個主要通過服務器的配置來實現這個技術,如果使用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>
解釋:第一句--開啟服務
第二句--默認時間是一個月
在下面是關于各種類型的資源的緩存時間設置
*請認真填寫需求信息,我們會在24小時內與您取得聯系。