天天看點

Http知道這些,開發Android才算合格!

前言

說起HTTP大家再熟悉不過了,無論是大學的課本上還是平時的工作中,幾乎每天都要和HTTP打交道。但是,就是這麼熟悉的老朋友,你真的是非常了解嗎?你能輕而易舉就回答出我下面的幾個問題嗎?

① OSI模型分為哪幾層?分别是什麼作用?

② Http協定屬于哪一層?與HTTP同一層的協定你還能列舉哪些協定?

③ 說出5種以上的HTTP請求方法

是不是看起來非常簡單,思考一下,能準确回答嗎?

對方不想和你說話,并向你扔了一張圖:

Http知道這些,開發Android才算合格!

1.定義

對于前面我提到的問題,我相信對于有些同學還是有點遺忘的,這很正常。就是在我們公司裡面,服務端的一些很不錯的同僚,你突然問他OSI的分層和對應作用,他們也不能完全說的明明白白。對于上面的第一個問題其實你大可不必都要說的清清楚楚的。但是很多和我日常工作息息相關的,或者說關系比較密切的我們還是需要了解清楚的。

簡單來講,HTTP協定它就是一種讓我們可以通過本地的工具(浏覽器、網絡爬蟲等等工具)通路遠端(伺服器)上的資源的一種協定。

舉一個例子:

Http知道這些,開發Android才算合格!

HTTP協定有哪些特點呢?

簡單快速:HTTP封包能夠被人讀懂,還允許簡單測試,降低了門檻, 對新人很友好

靈活:在 HTTP/1.0 中出現的 HTTP headers 讓協定擴充變得非常容易。隻要服務端和用戶端就新 headers 達成語義一緻,新功能就可以被輕松加入進來。

無連接配接:一個連接配接是由傳輸層來控制的,這從根本上不屬于HTTP的範圍。HTTP并不需要其底層的傳輸層協定是面向連接配接的,隻需要它是可靠的,或不丢失消息的(至少傳回錯誤)。在網際網路中,有兩個最常用的傳輸層協定:TCP是可靠的,而UDP不是。是以,HTTP依賴于面向連接配接的TCP進行消息傳遞,但連接配接并不是必須的。

無狀态:在同一個連接配接中,兩個執行成功的請求之間是沒有關系的。這就帶來了一個問題,使用者沒有辦法在同一個網站中進行連續的互動,比如在一個電商網站裡,使用者把某個商品加入到購物車,切換一個頁面後再次添加了商品,這兩次添加商品的請求之間沒有關聯,浏覽器無法知道使用者最終選擇了哪些商品。而使用HTTP的頭部擴充,HTTP Cookies就可以解決這個問題。把Cookies添加到頭部中,建立一個會話讓每次請求都能共享相同的上下文資訊,達成相同的狀态。

注意,HTTP本質是無狀态的,使用Cookies可以建立有狀态的會話。

2.封包

2.1 請求封包

哈哈通常來說,我們的Request是由幾個部分組成:請求行、請求頭部、一個空行、實體内容

看一下簡單的請求的封包結構:

Http知道這些,開發Android才算合格!

請求由以下元素組成:

  • 一個HTTP的method,經常是由一個動詞像

    GET

    ,

    POST

    或者一個名詞像

    OPTIONS

    HEAD

    來定義用戶端的動作行為。通常用戶端的操作都是擷取資源(GET方法)或者發送HTML form表單值(POST方法),雖然在一些情況下也會有其他操作。
  • 要擷取的資源的路徑,通常是上下文中就很明顯的元素資源的URL,它沒有protocol(

    http://

    ),domain(

    developer.mozilla.org

    ),或是TCP的port(HTTP一般在80端口)。
  • HTTP協定版本号。
  • 為服務端表達其他資訊的可選頭部headers。
  • 對于一些像POST這樣的方法,封包的body就包含了發送的資源,這與響應封包的body類似。

2.2 傳回封包

Http知道這些,開發Android才算合格!

響應封包包含了下面的元素:

  • HTTP協定版本号。
  • 一個狀态碼(status code),來告知對應請求執行成功或失敗,以及失敗的原因。
  • 一個狀态資訊,這個資訊是非權威的狀态碼描述資訊,可以由服務端自行設定。
  • HTTP headers,與請求頭部類似。
  • 可選項,比起請求封包,響應封包中更常見地包含擷取的資源body。

2.3 小結

HTTP是一種簡單可擴充的協定,其Client-Server的結構以及輕松擴充頭部資訊的能力使得HTTP可以和Web共同發展。

即使HTTP/2為了提高性能将HTTP封包嵌入到幀中這一舉措增加了複雜度,但是從Web應用的角度看,封包的基本結構沒有變化,從HTTP/1.0釋出起就是這樣的結構。會話流依舊簡單,通過一個簡單的 HTTP message monitor就可以檢視和糾錯。附帶接口傳回碼的意義對照:

1xx:訓示資訊——表示請求已接收,繼續處理

  2xx:成功——表示請求已經被成功接收,了解,接受

  3xx:重定向——要完成請求必須進行更進一步的操作

  4xx:用戶端錯誤——請求有文法錯誤或請求無法實作

  5xx:伺服器端錯誤——伺服器未能實作合法的請求

3 關于Cookie

HTTP Cookie(也叫Web Cookie或浏覽器Cookie)是伺服器發送到使用者浏覽器并儲存在本地的一小塊資料,它會在浏覽器下次向同一伺服器再發起請求時被攜帶并發送到伺服器上。通常,它用于告知服務端兩個請求是否來自同一浏覽器,如保持使用者的登入狀态。Cookie使基于無狀态的HTTP協定記錄穩定的狀态資訊成為了可能。

3.1 建立Cookie

Cookie就是伺服器按照約定的形式将需要用戶端(一般指浏覽器)緩存的資料放到響應頭裡面。浏覽器收到後便緩存起來。一般緩存的資訊有Cookie的過期時間、域、路徑、适用站點等等資訊。一般的格式如下:

Set-Cookie: <cookie名>=<cookie值>           

複制

一個簡單的例子,當伺服器第一次傳回時:

HTTP/1.0 200 OKContent-type: text/htmlSet-Cookie: yummy_cookie=chocoSet-Cookie: tasty_cookie=strawberry[頁面内容]           

複制

當浏覽器第二次通路同一站點時,會将Cookie的資訊帶到請求頭裡面:

GET /sample_page.html HTTP/1.1Host: www.example.orgCookie: yummy_cookie=choco; tasty_cookie=strawberry
3.2 兩種類型的Cookie           

複制

會話期Cookie:如果不設定Cookie的過期時間,那麼Cookie隻儲存在目前浏覽器配置設定的記憶體中,浏覽器被關閉時Cookie就失效了。但不是絕對的,有些浏覽器會有會話恢複的功能,就算浏覽器被關閉,下次打開時會自動全恢複,包括Cookie。

持久性Cookie:與會話期Cookie不同的是,持久性Cookie一般可以設定一個過期時間(Expires)或者有效時間(Max-Age),一般以檔案的形式存在硬碟中。

Set-Cookie: id=a3fWa; Expires=Wed, 12 Oct 2019 07:28:00 GMT;           

複制

複制

3.3 安全性

當機器處于不安全環境時,切記不能通過HTTP Cookie存儲、傳輸敏感資訊。

标記為

Secure

的Cookie隻應通過被HTTPS協定加密過的請求發送給服務端。但即便設定了

Secure

标記,敏感資訊也不應該通過Cookie傳輸,因為Cookie有其固有的不安全性,

Secure

标記也無法提供确實的安全保障。從 Chrome 52 和 Firefox 52 開始,不安全的站點(

http:

)無法使用Cookie的

Secure

标記。

為避免跨域腳本 (XSS) 攻擊,通過JavaScript的

Document.cookie

API無法通路帶有

HttpOnly

标記的Cookie,它們隻應該發送給服務端。如果包含服務端 Session 資訊的 Cookie 不想被用戶端 JavaScript 腳本調用,那麼就應該為其設定

HttpOnly

标記。

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly           

複制

關于Cookie,歐盟已經在2009/136/EC指令中提了相關要求,該指令已于2011年5月25日生效。雖然指令并不屬于法律,但它要求歐盟各成員國通過制定相關的法律來滿足該指令所提的要求。當然,各國實際制定法律會有所差别。

該歐盟指令的大意:在征得使用者的同意之前,網站不允許通過計算機、手機或其他裝置存儲、檢索任何資訊。自從那以後,很多網站都在網站聲明中添加了相關說明,告訴使用者他們的Cookie将用于何處。

4 Android應用

4.1 GET示例

Http知道這些,開發Android才算合格!

4.2 POST示例

Http知道這些,開發Android才算合格!