網站首頁 編程語言 正文
請求:
HTTP 請求報文由請求行、請求頭部、空行、請求包體4個部分組成,如下圖所示:
請求行:
請求行由方法字段、URL 字段 和HTTP 協議版本字段 3個部分組成,他們之間使用空格隔開。常用的 HTTP 請求方法有 GET、POST。
GET:
- 當客戶端要從服務器中讀取某個資源時,使用GET 方法。GET 方法要求服務器將URL 定位的資源放在響應報文的數據部分,回送給客戶端,即向服務器請求某個資源。
- 使用GET方法時,請求參數和對應的值附加在 URL 后面,利用一個問號(“?”)代表URL 的結尾與請求參數的開始,傳遞參數長度受限制,因此GET方法不適合用于上傳數據。
- 通過GET方法來獲取網頁時,參數會顯示在瀏覽器地址欄上,因此保密性很差。
POST:
- 當客戶端給服務器提供信息較多時可以使用POST 方法,POST 方法向服務器提交數據,比如完成表單數據的提交,將數據提交給服務器處理。
- GET 一般用于獲取/查詢資源信息,POST 會附帶用戶數據,一般用于更新資源信息。POST 方法將請求參數封裝在HTTP 請求數據中,而且長度沒有限制,因為POST攜帶的數據,在HTTP的請求正文中,以名稱/值的形式出現,可以傳輸大量數據。
請求頭:
請求頭部為請求報文添加了一些附加信息,由“名/值”對組成,每行一對,名和值之間使用冒號分隔。請求頭部通知服務器有關于客戶端請求的信息,典型的請求頭有:
請求頭 | 含義 |
---|---|
User-Agent | 請求的瀏覽器類型 |
Accept | 客戶端可識別的響應內容類型列表,星號“ * ”用于按范圍將類型分組,用“ / ”指示可接受全部類型,用“ type/* ”指示可接受 type 類型的所有子類型 |
Accept-Language | 客戶端可接受的自然語言 |
Accept-Encoding | 客戶端可接受的編碼壓縮格式 |
Accept-Charset | 可接受的應答的字符集 |
Host | 請求的主機名,允許多個域名同處一個IP 地址,即虛擬主機 |
connection | 連接方式(close或keepalive) |
Cookie | 存儲于客戶端擴展字段,向同一域名的服務端發送屬于該域的cookie |
空行:
最后一個請求頭之后是一個空行,發送回車符和換行符,通知服務器以下不再有請求頭。
請求包體:
請求包體不在GET方法中使用,而在POST方法中使用。POST方法適用于需要客戶填寫表單的場合。與請求包體相關的最常使用的是包體類型Content-Type和包體長度Content-Length。
響應:
響應報文格式說明
HTTP 響應報文由狀態行、響應頭部、空行、響應包體4個部分組成,如下圖所示:
狀態行:
狀態行由 HTTP 協議版本字段、狀態碼和狀態碼的描述文本3個部分組成,他們之間使用空格隔開。
狀態碼:狀態碼由三位數字組成,第一位數字表示響應的類型,常用的狀態碼有五大類如下所示:
狀態碼 | 含義 |
---|---|
1xx | 表示服務器已接收了客戶端請求,客戶端可繼續發送請求 |
2xx | 表示服務器已成功接收到請求并進行處理 |
3xx | 表示服務器要求客戶端重定向 |
4xx | 表示客戶端的請求有非法內容 |
5xx | 表示服務器未能正常處理客戶端的請求而出現意外錯誤 |
常見的狀態碼舉例:
狀態碼 | 含義 |
---|---|
200 OK | 客戶端請求成功 |
400 Bad Request | 請求報文有語法錯誤 |
401 Unauthorized | 未授權 |
403 Forbidden | 服務器拒絕服務 |
404 Not Found | 請求的資源不存在 |
500 Internal Server Error | 服務器內部錯誤 |
503 Server Unavailable | 服務器臨時不能處理客戶端請求(稍后可能可以) |
響應頭可能包括:
響應頭 | 含義 |
---|---|
Location Location | 響應報頭域用于重定向接受者到一個新的位置 |
Server Server | 響應報頭域包含了服務器用來處理請求的軟件信息及其版本 |
Vary | 指示不可緩存的請求頭列表 |
Connection | 連接方式 |
空行:
最后一個響應頭部之后是一個空行,發送回車符和換行符,通知服務器以下不再有響應頭部。
響應包體:
服務器返回給客戶端的文本信息
響應報文格式:
要想獲取響應報文,必須先發送請求報文給web服務器。服務器收到并解析瀏覽器(客戶端)發送的請求報文后,借助http協議,回復相對應的響應報文。可以用net/http包,創建一個最簡單的服務器,給瀏覽器回發送響應包。首先注冊處理函數http.HandleFunc(),設置回調函數handler。而后綁定服務器的監聽地址http.ListenAndserve()。這個服務器啟動后,當有瀏覽器發送請求,回調函數被調用,會向瀏覽器回復“hello world”作為網頁內容。當然,是按照http協議的格式進行回復。
HTTP服務端實現:
Go語言標準庫內建提供了net/http包,涵蓋了HTTP客戶端和服務端的具體實現。使用net/http包,我們可以很方便地編寫HTTP客戶端或服務端的程序。
package main import ( "fmt" "net/http" ) func main() { /** 注冊回調函數,該回調函數會在服務器被訪問時自動被調用 func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) pattern:訪問服務器文件位置 handler:回調函數名,函數必須是ResponseWriter, *Request類型作為參數 */ http.HandleFunc("/itzhuzhu", myHandlerFunc) /** 綁定服務器監聽地址 func ListenAndServe(addr string, handler Handler) error addr:要監聽的地址 handler:回調函數,為空則調用系統默認的回調函數 */ http.ListenAndServe("127.0.0.1:8000", nil) } /** ResponseWriter:寫給客戶端的數據內容 Request:從客戶端讀取到的數據內容 */ func myHandlerFunc(w http.ResponseWriter, r *http.Request) { w.Write([]byte("ResponseWriter Test")) fmt.Println("Header:", r.Header) fmt.Println("URL:", r.URL) fmt.Println("Method:", r.Method) fmt.Println("Host:", r.Host) fmt.Println("RemoteAddr:", r.RemoteAddr) fmt.Println("Body:", r.Body) }
HTTP客戶端實現:
客戶端模擬瀏覽器發送請求:
package main import ( "fmt" "net" "os" ) func main() { // 客戶端連接服務器 dial, err := net.Dial("tcp", "127.0.0.1:8000") errFunction("net.Dial err:", err) defer dial.Close() // 模擬瀏覽器 requstHttpHeader := "GET /itzhuzhu HTTP/1.1\r\nHost:127.0.0.1:8000\r\n\r\n" // 給服務器發送請求報文 dial.Write([]byte(requstHttpHeader)) buf := make([]byte, 1024) // 讀取服務器的回復 read, err := dial.Read(buf) errFunction("dial.Read err:", err) fmt.Println( string(buf[:read])) } func errFunction(describe string, err error) { if err != nil { fmt.Println(describe, err) os.Exit(1) } }
服務器發送的響應包體被保存在Body中。可以使用它提供的Read方法來獲取數據內容。保存至切片緩沖區中,拼接成一個完整的字符串來查看。
結束的時候,需要調用Body中的Close()方法關閉io。
package main import ( "fmt" "net/http" ) func main() { // 使用Get方法獲取服務器響應包數據 resp, err := http.Get("http://www.baidu.com") if err != nil { fmt.Println("Get err:", err) return } defer resp.Body.Close() // 獲取服務器端讀到的數據 fmt.Println("Status = ", resp.Status) // 狀態 fmt.Println("StatusCode = ", resp.StatusCode) // 狀態碼 fmt.Println("Header = ", resp.Header) // 響應頭部 fmt.Println("Body = ", resp.Body) // 響應包體 buf := make([]byte, 4096) // 定義切片緩沖區,存讀到的內容 var result string // 獲取服務器發送的數據包內容 for { n, err := resp.Body.Read(buf) // 讀body中的內容。 if n == 0 { fmt.Println("Body.Read err:", err) break } result += string(buf[:n]) // 累加讀到的數據內容 } // 打印從body中讀到的所有內容 fmt.Println("result = ", result) }
原文鏈接:https://blog.csdn.net/weixin_45477086/article/details/122977970
相關推薦
- 2022-11-15 SQL?Server?ISNULL?不生效原因及解決_MsSql
- 2022-07-13 CSS 不需要清除浮動的圣杯布局~面試可能會問
- 2022-07-14 使用react-activation實現keepAlive支持返回傳參_React
- 2022-06-12 C語言動態規劃多種背包問題分析講解_C 語言
- 2022-07-21 安裝MiniConda和Pytorch以及Cuda的筆記及心得
- 2023-03-05 Python協程的四種實現方式總結_python
- 2022-07-22 HttpClient如何自定義重試方法
- 2022-05-05 R語言因子類型的實現_R語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支