天天看點

Android-Http

參考文章:

  • https://mp.weixin.qq.com/s/38GrbReICfu54-nEWylqIQ
  • https://mp.weixin.qq.com/s/qSQqFRuD4fwVoFdkmGNRpw

    HTTP相關知識使我們面試或者實際開發中經常用到的,今天我們來做個總結。

1.Http的簡介

1.1 Http的含義

HTTP 全稱是 HyperText Transfer Protocal 即超文本傳輸協定。我們知道OSI模型把網絡通信的工作分為7層,分别是:是實體層、資料鍊路層、網路層、傳輸層、話路層、表示層和應用層。而Http協定是應用層協定。當你上網浏覽網頁的時候,浏覽器和 web 伺服器之間就會通過 HTTP 在 Internet 上進行資料的發送和接收。HTTP是一個基于請求/響應模式的、無狀态的協定,即我們通常所說的 Request/Response。補充:HTTP,UDP都是無狀态協定,而TCP,FTP是有狀态協定,關于什麼是無狀态協定可以簡單了解為:請求都是獨立的,一次Request對應一次Response。兩次相鄰的請求沒有直接聯系。但開發中的實際情況通常是,在 http 協定的基礎上,web 應用引入 cookies,session,application 來保持 web 應用之間的狀态。

1.2 Http的特點

  • 支援用戶端/伺服器模式
  • 簡單快速:客戶向伺服器請求服務時,隻需傳送請求方法和路徑。由于 HTTP 協定簡單,使得 HTTP 伺服器的程式規模小,因而通信速度很快
  • 靈活:HTTP 允許傳輸任意類型的資料對象。正在傳輸的類型由 Content-Type 加以标記
  • 無連接配接:無連接配接的含義是限制每次連結隻處理一個請求。伺服器處理完哭護的請求,并收到客戶的應答後,即斷開連結,采用這種方式可以節省傳輸時間
  • 無狀态:HTTP 協定是無狀态協定。無狀态是指協定對于事物處理沒有記憶能力。缺少狀态意味着如果後續處理需要前面的資訊,則它必須重傳,這樣可能會導緻每次連接配接傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快

1.3 網絡協定四層?

參考:https://blog.csdn.net/cc1949/article/details/79063439

我們剛才說了OSI模型把網絡通信的工作分為7層,但實際應用中還是TCP/IP的四層結構,4層是指TCP/IP四層模型,主要包括:應用層、運輸層、網際層和網絡接口層。

4層協定和對應的标準7層協定的關系如下圖:

Android-Http

我們來一張經典的4層結構圖說明一下:

Android-Http

那我們就參考上圖分别說一下與HTTP協定密切相關的協定:

1.3.1 傳輸層的TCP(確定可靠性的協定)

TCP 位于傳輸層,提供可靠的位元組流服務。所謂的位元組流服務( Byte Stream Service )是指,為了友善傳輸,将大塊資料分割成以封包段( segment )為機關的資料包進行管理。而可靠的傳輸服務是指,能夠把資料準确可靠地傳給對方.

這裡還要着重講解一下TCP連接配接的3次握手:

為了準确無誤地将資料送達目标處, TCP 協定采用了三次握手( three-way handshaking )政策。

握手過程中使用了 TCP 的标志( flag ) —— SYN ( synchronize ) 和ACK ( acknowledgement )。發送端首先發送個帶 SYN 标志的資料包給對方。接收端收到後,回傳一個帶有 SYN/ACK 标志的資料包以示傳達确認資訊。最後,發送端再回傳一個帶 ACK 标志的資料包,代表 “ 握手 ” 結束。若在握手過程中某個階段莫名中斷, TCP 協定會再次以相同的順序發送相同的資料包。

如圖所示:

Android-Http

1.3.2 網絡層的IP

IP 協定的作用是把各種資料包傳送給對方。而要保證确實傳送到對方那裡,則需要滿足各類條件。其中兩個重要的條件是 IP 位址和 MAC位址( Media Access Control Address )。IP 位址指明了節點被配置設定到的位址, MAC 位址是指網卡所屬的固定位址。 IP 位址可以和 MAC 位址進行配對。 IP 位址可變換,但 MAC位址基本上不會更改。IP使用 ARP 協定憑借 MAC 位址進行通信

2.URL詳解

3.1 URL含義

URL(Uniform Resource Locator)是統一資源定位符的簡稱,有時候也被俗稱為網頁位址(網址),是網際網路上标準的資源的位址。

3.2 URL構成

URL構成的通用格式為:schema://host[:port#]/path/…/[?query-string][#anchor]

我們來分析各部分的含義:

名稱 功能
schema 通路伺服器以擷取資源時要使用哪種協定,比如,http,https 和 FTP 等
host HTTP 伺服器的 IP 位址或域名,IP位址是一個最原始的東西,必須通過IP位址才可以找到其他的計算機;而域名隻是為了人們記的友善,給出的一個名字。域名的IP位址綁定了以後,當别人通路這個域名的時候就可以通過DNS解析成IP,再進行通路。
port HTTP 伺服器的預設端口是 80,這種情況下端口号可以省略,如果使用了别的端口,必須指明,例如http://www.cnblogs.com:8080
path 通路資源的路徑
query-string 發給 http 伺服器的資料 ,比如參數
#anchor 錨,什麼是錨呢?比如:http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name這個連結,錨部分就是從“#”開始到最後。本例中的錨部分是“name”。錨不是一個URL必須的部分 。預設情況下,Google的網絡蜘蛛忽視URL的#部分。但是,如果你希望Ajax生成的内容被浏覽引擎讀取,那麼URL中可以使用"#!",這裡我們不過多解釋

用事實說話,比如:

http://www.mywebsite.com/sj/test/test.aspx?name=sviergn&x=true#stuff

其中

名稱 對應的字段
Schema http
host www.mywebsite.com
path /js/test/test.aspx
Query-string name=sviergn&x=true
anchor stuff

再來張比較直覺的圖

Android-Http

3.Http 詳解

3.1 Http請求詳解

HTTP 的請求封包分為三個部分:請求行、請求頭、請求體

3.1.1請求行

請求行(Request line)分為三個部分:請求方法、請求位址和協定版本

是以請求行的格式一般是:

Android-Http

舉例:

GET /app/appUserAction!getUserLogin.do.html HTTP/1.1

請求位址就是我們要請求伺服器的位址,協定版本是我們Http的版本比如:Http1.0、Http1.1等版本。

我們主要來說一下請求方法:

HTTP/1.1 協定中共定義了八種方法(也叫“動作”)來以不同的方式操作指定的資源.

方法名 功能
GET 向指定的資源發出“顯示”請求,使用 GET 方法應該隻用在讀取資料上,而不應該用于産生“副作用”的操作中
POST 指定資源送出資料,請求伺服器進行處理(例如送出表單或者上傳檔案)。資料被包含在請求文本中。這個請求可能會建立新的資源或者修改現有資源,或兩者皆有。
PUT 向指定資源位置上傳其最新内容
DELETE 請求伺服器删除 Request-URI 所辨別的資源
OPTIONS 使伺服器傳回該資源所支援的所有HTTP請求方法。用*來代替資源名稱,向 Web 伺服器發送 OPTIONS 請求,可以測試伺服器功能是否正常運作
HEAD 與 GET 方法一樣,都是向伺服器發出指定資源的請求,隻不過伺服器将不傳回資源的本文部分,它的好處在于,使用這個方法可以在不必傳輸全部内容的情況下,就可以擷取其中關于該資源的資訊(原資訊或稱中繼資料)
TRACE 顯示伺服器收到的請求,主要用于測試或診斷
CONNECT HTTP/1.1 中預留給能夠将連接配接改為通道方式的代理伺服器。通常用于 SSL 加密伺服器的連結(經由非加密的 HTTP 代理伺服器)

其中,最常見的是 GET 和 POST 方法,如果是 RESful 接口的話一般會用到 PUT、DELETE、GET、POST(分别對應增删查改)

補充:

RESful 是一種軟體架構風格、設計風格,而不是标準,隻是提供了一組設計原則和限制條件。它主要用于用戶端和伺服器互動類的軟體。基于這個風格設計的軟體可以更簡潔,更有層次,更易于實作緩存等機制。

3.1.2請求頭

請求頭可用于傳遞一些附加資訊,格式為:鍵: 值,注意冒号後面有一個空格:

如圖,是Fiddler抓包擷取的請求頭資訊:

GET省略包含參數的請求......... HTTP/1.1
Host: 省略.........
Connection: keep-alive
User-Agent: Mozilla/5.0 (Linux; U; Android 9; zh-cn; DUK-AL20 Build/HUAWEIDUK-AL20) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/9.0 Mobile Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,image/sharpp,image/apng,image/tpg,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh-CN;q=0.8,en-GB;q=0.6,en-US;q=0.4           

複制

這個請求頭資訊并不能代表所有請求頭資訊,是以我們來說一說請求頭的一些知識點:

首先,請求頭通常用來傳遞一些附加資訊,格式為:鍵: 值,注意冒号後面有一個空格:

請求和響應常見通用的 Header

名稱 作用
Content-Type 請求體/響應體的類型,如:text/plain、application/json
Accept 說明接收的類型,可以多個值,用,(英文逗号)分開
Content-length 請求體/響應體的長度,機關位元組
Content-Encoding 請求體/響應體的編碼格式,如 gzip、deflate
Accept-Encoding 告知對方我方接受的 Content-Encoding
ETag 給目前資源的辨別,和Last-Modified、If-None-Match、If-Modified-Since配合,用于緩存控制
Cache-Control 取值一般為no-cache、max-age=xx,xx為整數,表示資源緩存有效期(秒)

請求Header内包含常用資訊如下:

名稱 作用
Authorization 用于設定身份認證資訊
User-Agent 使用者辨別,如:OS 和浏覽器的類型和版本
If-Modified-Since 值為上一次伺服器傳回的Last-Modified值,用于确定某個資源是否被更改過,沒有更改過就從緩存中讀取
If-None-Match 值為上一次伺服器傳回的 ETag 值
Cookie 已有的Cookie
Referer 辨別請求引用自哪個位址,比如你從頁面 A 跳轉到頁面 B 時,值為頁面 A 的位址
Host 請求的主機和端口号

3.1.3 請求體

請求體(又叫請求正文)是 post 請求方式中的請求參數,以 key = value 形式進行存儲,多個請求參數之間用&連接配接,如果請求當中請求體,那麼在請求頭當中的 Content-Length 屬性記錄的就是該請求體的長度,就是我們通常通路伺服器需要傳的參數資訊,如:

http://www.baidu.com/login.do?account=123456&password=99fe158e8abc9ffbd09eab0ec9d81781

根據應用場景的不同,HTTP 請求的請求體有三種不同的形式

第一種:

移動開發者常見的,請求體是任意類型的,伺服器不會解析請求體,請求體的處理需要自己解析,如圖:

Android-Http

第二種:

第二種和第三種都有固定的格式,是伺服器端開發人員最先了解的兩種。這裡的格式要求就是 URL 中 Query String(可以了解為參數) 的格式要求:多個鍵值對之間用&連接配接,鍵與值之間用=連接配接,且隻能用 ASCII 字元,非 ASCII 字元需使用UrlEncode編碼。

Android-Http

第三種:

第三種請求體被分成多個部分,檔案上傳 時會被使用,這種格式最先是被用于郵件傳輸中,每個字段/檔案都被 boundary(Content-Type中指定的)分成單獨的段,每段以--加 boundary 開頭,然後是該段的描述頭,描述頭之後空一行接内容,請求結束的辨別為 boundary 後面加--

Android-Http

3.2 Http響應詳解

HTTP 響應的格式上除狀态行(第一行)與請求封包的請求行不一樣之外,其他的就格式而言是一樣的。

Http響應主藥由三部分:響應狀态行、響應頭、響應體.

3.2.1 響應狀态行

Http的響應狀态行格式如下:

Android-Http

舉例:

HTTP/1.1 200 OK

那我們說一下常見響應碼的含義:

狀态碼 對應資訊
1xx 提示資訊—表示請求已接收,繼續處理
2xx 用于表示請求已被成功接收、了解、接收
3xx 用于表示資源(網頁等)被永久轉移到其它 URL,也就是所謂的重定向
4xx 用戶端錯誤—請求有文法錯誤或者請求無法實作
5xx 務器端錯誤—伺服器未能實作合法的請求

3.2.2 響應頭

響應頭同樣可用于傳遞一些附加資訊,

注:隻是部分資訊。
Server: nginx/1.12.2
Date: Wed, 30 Jan 2019 02:06:41 GMT
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: JSESSIONID=96C4243B3715D585A3699BF9451D5FE3; Path=/; HttpOnly
Content-Language: zh-CN           

複制

常見的響應Header

名稱 作用
Date 伺服器的日期
Last-Modified 該資源最後被修改的時間
Transfer-Encoding 取值一般為 chunked,出現在 Content-Length 不能确定的情況下,表示伺服器不知道響應闆體的資料大小,一般同時出現Content-Encoding響應頭
Set-Cookie 設定 Cookie
Location 重定向到另一個 URL,如輸入浏覽器就輸入 baidu.com 回車,會自動跳轉到https://www.baidu.com 就是通過這個響應頭控制的
Server 背景伺服器

3.2.3 響應體

響應體也就是網頁的正文内容,一般在響應頭中會用 Content-Length 來明确響應體的長度,便于浏覽器接收,對于大資料量的正文資訊,也會使用 chunked 的編碼方式。

Http的相關知識其實有很多,我們這裡隻是說了常見的部分,大家可以深入了解一下,再次感謝參考文章。