HTTP協議

HTTP協議

1、HTTP協議簡介

  • HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用於從(WWW:World Wide Web,簡萬維網 )服務器傳輸超文本到本地瀏覽器的傳送協議。
  • HTTP協議工做於B/S架構上
    瀏覽器做爲HTTP客戶端經過URL向HTTP服務端即WEB服務器發送請求Request。 Web服務器根據接收到的請求後,向客戶端發送響應信息Response。
  • HTTP協議是基於TCP/IP通訊協議來傳遞數據的(HTML 文件, 圖片文件等)

一、什麼是互聯網

  • 互聯網=物理鏈接介質+互聯網協議

二、互聯網創建的目的?

  • 數據傳輸打破地域限制,不然的話,我想得到對方主機上的數據,只能拿着硬盤去對方主機拷貝

三、什麼是上網?

  • 用戶上網的過程即瀏覽器向服務端發送請求,而後將服務端主機的文本文件下載到本地顯示的過程。而瀏覽器與服務器之間走的HTTP協議。
  • 學習前端開發就是爲了編排好一個文本文件存放到服務端主機,而後提供給瀏覽器下載顯示的。

2、http協議發展經歷

一、HTTP/0.9

第一個HTTP協議誕生於1989年3月,已過期。php

  • 它的組成極其簡單:
    1. 只容許客戶端發送GET這一種請求
    2. 不支持請求頭。
    3. 因爲沒有請求頭,形成了HTTP 0.9協議只支持一種內容,即純文本。不過網頁仍然支持用HTML語言格式化,同時沒法插入圖片。
  • 無狀態性
    1. 一次HTTP 0.9的傳輸首先要創建一個由客戶端到Web服務器的TCP鏈接,由客戶端發起一個請求,而後由Web服務器返回頁面內容,而後鏈接會關閉。若是請求的頁面不存在,也不會返回任何錯誤碼。
    2. 因而可知,HTTP協議的無狀態特色在其第一個版本0.9中已經成型。
  • HTTP 0.9協議文檔:
    1. HTTP 0.9協議文檔

二、HTTP/1.0

HTTP/1.0是HTTP協議的第二個版本,至今仍被普遍採用。首次在通信中指定版本號,相對於HTTP 0.9 增長了以下主要特性:html

  • 支持請求頭與響應頭
  • Response響應以一個響應狀態行開始
  • Response包含的內容不僅限於超文本
  • 開始支持客戶端經過POST方法向Web服務器提交數據,並支持GET、HEAD、POST方法
  • 支持長鏈接Keepalive(但默認仍是使用短鏈接)
  • 緩存機制以及身份認證

三、HTTP/1.1

  • HTTP/1.1是HTTP協議的第三個版本,是目前主流的HTTP協議版本
  • HTTP 1.1引入了許多關鍵性能優化:keepalive鏈接,請求流水線,chunked編碼傳輸,字節範圍請求等

Persistent Connection(keepalive鏈接)

  • 長鏈接:
    1. 容許HTTP設備在事務處理結束以後將TCP鏈接保持在打開的狀態,以便將來的HTTP請求重用如今的鏈接,直到客戶端或服務器端決定將其關閉爲止。
  • HTTP1.1對比HTTP1.0?
    1. 在HTTP1.0中使用長鏈接須要添加請求頭 Connection: Keep-Alive,而在HTTP 1.1 全部的鏈接默認都是長鏈接,除非特殊聲明不支持( HTTP請求報文首部加上Connection: close )

Pipelining(請求流水線)

  • 支持持久鏈接的客戶端能夠「流水線」它的請求(即,發送多個請求而無需等待每一個響應)。服務器必須按照與收到請求的相同順序來向這些請求發送響應。

chunked編碼傳輸

  • 介紹:
    1. 該編碼將實體分塊傳送並逐塊標明長度,直到長度爲0塊表示傳輸結束, 這在實體長度未知時特別有用(好比由數據庫動態產生的數據)
  • 傳輸編碼和分塊編碼:
    1. 當響應頭裏包含Transfer-Encoding: chunked,表明分塊編碼,會把「報文」分割成若干個大小已知的塊,塊之間是緊挨着發送的,這樣就不須要在發送以前知道整個報文的大小了,也意味着不須要寫回Content-Length首部了。
  • 分塊傳輸的應用:
    1. 當使用持久鏈接時,在服務器發送主體內容以前,必須計算出主體內容的大小,而後放到響應頭裏(Content-Length:主體的字節數)發送給客戶端。
    2. 若是服務器動態建立內容,可能在發送以前沒法知道主體大小,分塊編碼就是爲了解決這種狀況:服務器把主體逐塊發送,說明每一塊的大小。服務器再用大小爲0的塊做爲結束塊。,爲下一個響應作準備,此時響應頭裏便再也不須要Content-Length了
    3. 除非使用了分塊編碼Transfer-Encoding: chunked,不然響應頭首部必須使用Content-Length首部。 摘自HTTP/1.1:https://tools.ietf.org/html/rfc2616
  • 關於Content-Length首部:
    1. 若是請求頭包含Accept-Encoding': 'gzip',則服務端會將內容壓縮後返回,內容的Content-Length長度是壓縮後的長度,
    2. 若是請求頭不包含Accept-Encoding': 'gzip',
    3. 服務器就不會採起gzip壓縮,同時我司服務器設定也不進行分塊編碼。因此返回響應頭的Content-Length首部是必須的,可是這個值的大小確定是沒有進行過壓縮的文件大小。

字節範圍請求

  • HTTP1.1支持傳送內容的一部分。比方說,當客戶端已經有內容的一部分,爲了節省帶寬,能夠只向服務器請求一部分。該功能經過在請求消息中引入了range頭域來實現,它容許只請求資源的某個部分。在響應消息中Content-Range頭域聲明瞭返回的這部分對象的偏移值和長度。若是服務器相應地返回了對象所請求範圍的內容,則響應碼206(Partial Content)

HTTP 1.1還新增了以下特性:

  • 請求消息和響應消息都應支持Host頭域:
    1. 在HTTP1.0中認爲每臺服務器都綁定一個惟一的IP地址,所以,請求消息中的URL並無傳遞主機名(hostname)。但隨着虛擬主機技術的發展,在一臺物理服務器上能夠存在多個虛擬主機(Multi-homed Web Servers),而且它們共享一個IP地址。所以,Host頭的引入就頗有必要了。
  • 新增了一批Request method
    1. HTTP1.1增長了OPTIONS,PUT, DELETE, TRACE, CONNECT方法
  • 緩存處理
    1. HTTP/1.1在1.0的基礎上加入了一些cache的新特性,引入了實體標籤,通常被稱爲e-tags,新增更爲強大的Cache-Control頭。

四、HTTP/2.0

HTTP 2.0是下一代HTTP協議,目前應用還很是少。主要特色有:前端

  • 多路複用(二進制分幀)
    1. HTTP 2.0最大的特色: 不會改動HTTP 的語義,HTTP 方法、狀態碼、URI 及首部字段,等等這些核心概念上一如往常,卻能致力於突破上一代標準的性能限制,改進傳輸性能,實現低延遲和高吞吐量。而之因此叫2.0,是在於新增的二進制分幀層。在二進制分幀層上, HTTP 2.0 會將全部傳輸的信息分割爲更小的消息和幀,並對它們採用二進制格式的編碼 ,其中HTTP1.x的首部信息會被封裝到Headers幀,而咱們的request body則封裝到Data幀裏面。
    2. HTTP 2.0 通訊都在一個鏈接上完成,這個鏈接能夠承載任意數量的雙向數據流。相應地,每一個數據流以消息的形式發送,而消息由一或多個幀組成,這些幀能夠亂序發送,而後再根據每一個幀首部的流標識符從新組裝。
  • 頭部壓縮
    1. 當一個客戶端向相同服務器請求許多資源時,像來自同一個網頁的圖像,將會有大量的請求看上去幾乎一樣的,這就須要壓縮技術對付這種幾乎相同的信息。
  • 隨時復位
    1. HTTP1.1一個缺點是當HTTP信息有必定長度大小數據傳輸時,你不能方便地隨時中止它,中斷TCP鏈接的代價是昂貴的。使用HTTP2的RST_STREAM將能方便中止一個信息傳輸,啓動新的信息,在不中斷鏈接的狀況下提升帶寬利用效率。
  • 服務器端推流: Server Push
    1. 客戶端請求一個資源X,服務器端判斷也許客戶端還須要資源Z,在無需事先詢問客戶端狀況下將資源Z推送到客戶端,客戶端接受到後,能夠緩存起來以備後用。
  • 優先權和依賴
    1. 每一個流都有本身的優先級別,會代表哪一個流是最重要的,客戶端會指定哪一個流是最重要的,有一些依賴參數,這樣一個流能夠依賴另一個流。優先級別能夠在運行時動態改變,當用戶滾動頁面時,能夠告訴瀏覽器哪一個圖像是最重要的,你也能夠在一組流中進行優先篩選,可以忽然抓住重點流。

3、http協議之請求Request

  • 資源:任何事物,只要有被引用到的必要,它就是一個資源。資源能夠是一個實體,也能夠是抽象概念。好比在瀏覽器中看到的文本,視頻,圖片等等都是實體資源。也能夠是抽象的概念,好比兩我的的關係......
  • URI(統一資源標誌符)是給資源進行標識的,在web中的惟一標識就是URI
  • URL(統一資源定位符)是描述資源地址的。URL能夠說是URI的子集,經過定位的方式實現的URI
  • URI相似身份證是惟一的,URL相似家庭住址xx省/xx市/xx村/xx號街道/xx號樓/Alex

一、URL

http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1以這個URL爲例,介紹下普通URL的各部分組成:java

  1. 協議部分:http://
    • 該URL的協議部分爲「http:」,在"HTTP"後面的「//」爲分隔符。這表明網頁使用的是HTTP協議。在Internet中可使用多種協議,如HTTP,FTP等等。
    • 若是不寫,瀏覽器會自動補全,但必須有
  2. 域名部分:www.aspxfans.com
    • 一個URL中,也可使用IP地址做爲域名使用
    • 必須有
  3. 端口部分:8080
    • 跟在域名後面的是端口,域名和端口之間使用「:」做爲分隔符。
    • 端口不是一個URL必須的部分,若是省略端口部分,將採用默認端口80
  4. 虛擬目錄部分:/news/
    • 從域名後的第一個「/」開始到最後一個「/」爲止,是虛擬目錄部分。
    • 虛擬目錄也不是一個URL必須的部分
  5. 文件名部分:index.asp
    • 從域名後的最後一個「/」開始到「?」爲止,是文件名部分,若是沒有「?」,則是從域名後的最後一個「/」開始到「#」爲止,是文件部分,若是沒有「?」和「#」,那麼從域名後的最後一個「/」開始到結束,都是文件名部分。
    • 文件名部分也不是一個URL必須的部分,若是省略該部分,則使用默認的文件名
  6. 參數部分:boardID=5&ID=24618&page=1
    • 從「?」開始到「#」爲止之間的部分爲參數部分,又稱搜索部分、查詢部分。參數能夠容許有多個參數,參數與參數之間用「&」做爲分隔符。
    • 參數部分非必須
  7. 錨部分:#name
    • 從「#」開始到最後,都是錨部分。
    • 錨部分也不是一個URL必須的部分

二、URI

HTTP使用統一資源標識符(Uniform Resource Identifiers, URI)用來惟一的標識一個資源。Web上可用的每種資源如HTML文檔、圖像、視頻片斷、程序等都是一個URI來定位的python

  1. URI通常由三部組成:
    • ①訪問資源的命名機制
    • ②存放資源的主機名
    • ③資源自身的名稱,由路徑表示,着重強調於資源。
  2. URL是uniform resource locator,統一資源定位器,它是一種具體的URI,即URL能夠用來標識一個資源,並且還指明瞭如何locate這個資源。
  3. URL是Internet上用來描述信息資源的字符串,主要用在各類WWW客戶程序和服務器程序上,特別是著名的Mosaic。
  4. 採用URL能夠用一種統一的格式來描述各類信息資源,包括文件、服務器的地址和目錄等。
  5. URL通常由三部組成:
    • ①協議(或稱爲服務方式)
    • ②存有該資源的主機IP地址(有時也包括端口號)
    • ③主機資源的具體地址。如目錄和文件名等
  6. URN,uniform resource name,統一資源命名,是經過名字來標識資源,好比mailto:java-net@java.sun.com。
    • URI是以一種抽象的,高層次概念定義統一資源標識,而URL和URN則是具體的資源標識的方式。URL和URN都是一種URI。籠統地說,每一個 URL 都是 URI,但不必定每一個 URI 都是 URL。這是由於 URI 還包括一個子類,即統一資源名稱 (URN),它命名資源但不指定如何定位資源。上面的 mailto、news 和 isbn URI 都是 URN 的示例。
    • 在Java的URI中,一個URI實例能夠表明絕對的,也能夠是相對的,只要它符合URI的語法規則。而URL類則不只符合語義,還包含了定位該資源的信息,所以它不能是相對的。
    • 在Java類庫中,URI類不包含任何訪問資源的方法,它惟一的做用就是解析。 相反的是,URL類能夠打開一個到達資源的流。

三、請求格式

客戶端發送一個HTTP請求到服務器的請求消息格式爲:請求行(request line)、請求頭部(header)、空行和請求數據四個部分組成。mysql

請求行以一個方法GET或POST開頭,以空格分開,後面跟着請求的URI和協議的版本。詳細解釋以下
GET /linhaifeng/p/7278389.html HTTP/1.1
Host: www.cnblogs.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9


#第一部分:請求行,用來講明請求類型,要訪問的資源以及所使用的HTTP版本.
GET說明請求類型爲GET
/linhaifeng/p/7278389.html爲要訪問的資源
該行的最後一部分說明使用的是HTTP1.1版本

#第二部分:從第二行起爲請求頭部,緊接着請求行(即第一行)以後,用來講明服務器要使用的附加信息
HOST將指出請求的目的地.
User-Agent,服務器端和客戶端腳本都能訪問它,它是瀏覽器類型檢測邏輯的重要基礎.該信息由你的瀏覽器來定義,而且在每一個請求中自動發送等等

#第三部分:空行,請求頭部後面的空行是必須的
即便第四部分的請求數據爲空,也必須有空行。

#第四部分:請求數據也叫主體,能夠添加任意的其餘數據。
這個例子的請求數據爲空。只有POST方法纔有請求體,能夠用瀏覽器登陸一個網站,輸錯帳號密碼來抓取POST請求
POST / HTTP1.1
Host:www.wrox.com
User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Content-Type:application/x-www-form-urlencoded
Content-Length:40
Connection: Keep-Alive

name=Professional%20Ajax&publisher=Wiley

Request請求詳解
Request請求詳解
#一、Http協議定義了不少與服務器交互的方法
HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

#二、瞭解下各個方法的大體意義
GET     請求指定的頁面信息,並返回實體主體。
HEAD     相似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭
POST     向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會致使新的資源的創建和/或已有資源的修改。
PUT     從客戶端向服務器傳送的數據取代指定的文檔的內容。
DELETE      請求服務器刪除指定的頁面。
CONNECT     HTTP/1.1協議中預留給可以將鏈接改成管道方式的代理服務器。
OPTIONS     容許客戶端查看服務器的性能。
TRACE     回顯服務器收到的請求,主要用於測試或診斷。

#三、一個URL地址用於描述一個網絡上的資源,而HTTP中最基本的四個方法GET, POST, PUT, DELETE就對應着對這個資源的查,改,增,刪4個操做。

#四、 咱們最多見的就是GET和POST了。GET通常用於獲取/查詢資源信息,而POST通常用於更新資源信息.

HTTP請求方法
HTTP請求方法
#一、區別1: 參數的組織方式不一樣
GET提交的數據會放在URL以後,以?分割URL和傳輸數據,參數之間以&相連,
例 如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0 %E5%A5%BD。若是數據是英文字母/數字,原樣發送,若是是空格,轉換爲+,若是是中文/其餘字符,則直接把字符串用BASE64加密,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX爲該符號以16進製表示的ASCII。

POST方法是把提交的數據放在HTTP包的Body中.
所以,GET提交的數據會在地址欄中顯示出來,而POST提交,地址欄不會改變

#二、區別2:傳輸數據大小限制
首先聲明:HTTP協議沒有對傳輸的數據大小進行限制,HTTP協議規範也沒有對URL長度進行限制。

而在實際開發中存在的限制主要有:
GET:特定瀏覽器和服務器對URL長度有限制,例如 IE對URL長度的限制是2083字節(2K+35)。對於其餘瀏覽器,如Netscape、FireFox等,理論上沒有長度限制,其限制取決於操做系 統的支持。
所以對於GET提交時,傳輸數據就會受到URL長度的 限制。

POST:因爲不是經過URL傳值,理論上數據不受 限。但實際各個WEB服務器會規定對post提交數據大小進行限制,Apache、IIS6都有各自的配置。

能夠簡單總結爲:
GET提交的數據大小有限制(由於瀏覽器對URL的長度有限制),而POST方法提交的數據沒有限制.
GET方式須要使用Request.QueryString來取得變量的值,而POST方式經過Request.Form來獲取變量的值。

#三、區別3:安全性
POST的安全性要比GET的安全性高。好比:經過GET提交數據,用戶名和密碼將明文出如今URL上,由於(1)登陸頁面有可能被瀏覽器緩存;(2)其餘人查看瀏覽器的歷史紀錄,那麼別人就能夠拿到你的帳號和密碼了,除此以外,使用GET提交數據還可能會形成Cross-site request forgery攻擊

GET與POST的區別
GET與POST的區別

4、http協議之響應Response

服務器接收並處理客戶端發過來的請求後會返回一個HTTP的響應消息Response
HTTP響應也由四個部分組成,分別是:狀態行、消息報頭、空行和響應正文。web

  1. 第一部分:狀態行,由HTTP協議版本號, 狀態碼, 狀態消息 三部分組成。
    • 第一行爲狀態行,(HTTP/1.1)代表HTTP版本爲1.1版本,狀態碼爲200,狀態消息爲(ok)
  2. 第二部分:消息報頭,用來講明客戶端要使用的一些附加信息,
    • Date:生成響應的日期和時間;
    • Content-Type:指定了MIME類型的HTML(text/html),編碼類型是UTF-8
  3. 第三部分:空行,消息報頭後面的空行是必須的
  4. 第四部分:響應正文,服務器返回給客戶端的文本信息。
    • 空行後面的html部分爲響應正文。

5、http響應狀態碼

狀態代碼有三位數字組成,第一個數字定義了響應的類別,共分五種類別:sql

  • 1xx:Informational指示信息--表示請求已接收,繼續處理
  • 2xx:Success成功--表示請求已被成功接收、理解、接受
  • 3xx:Redirection重定向--要完成請求必須進行更進一步的操做
  • 4xx:Client Error客戶端錯誤--請求有語法錯誤或請求沒法實現
  • 5xx:Server Error服務器端錯誤--服務器未能實現合法的請求

常見狀態碼:

  • 200 OK //客戶端請求成功
  • 400 Bad Request //客戶端請求有語法錯誤,不能被服務器所理解
  • 401 Unauthorized //請求未經受權,這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用
  • 403 Forbidden //服務器收到請求,可是拒絕提供服務
  • 404 Not Found //請求資源不存在,eg:輸入了錯誤的URL
  • 500 Internal Server Error //服務器發生不可預期的錯誤
  • 503 Server Unavailable //服務器當前不能處理客戶端的請求,一段時間後可能恢復正常
  • 更多狀態碼

6、http協議完整工做流程

HTTP協議定義Web客戶端如何從Web服務器請求Web頁面,以及服務器如何把Web頁面傳送給客戶端。HTTP協議採用了請求/響應模型。客戶端向服務器發送一個請求報文,請求報文包含請求的方法、URL、協議版本、請求頭部和請求數據。服務器以一個狀態行做爲響應,響應的內容包括協議的版本、成功或者錯誤代碼、服務器信息、響應頭部和響應數據。
如下是 HTTP 請求/響應的步驟: 數據庫

一、客戶端鏈接到Web服務器

一個HTTP客戶端,一般是瀏覽器,與Web服務器的HTTP端口(默認爲80)創建一個TCP套接字鏈接。編程

二、發送HTTP請求

經過TCP套接字,客戶端向Web服務器發送一個文本的請求報文,一個請求報文由請求行、請求頭部、空行和請求數據4部分組成。

三、服務器接受請求並返回HTTP響應

Web服務器解析請求,定位請求資源。服務器將資源複本寫到TCP套接字,由客戶端讀取。一個響應由狀態行、響應頭部、空行和響應數據4部分組成。

四、釋放鏈接TCP鏈接

若connection 模式爲close,則服務器主動關閉TCP鏈接,客戶端被動關閉鏈接,釋放TCP鏈接;若connection 模式爲keepalive,則該鏈接會保持一段時間,在該時間內能夠繼續接收請求;

五、客戶端瀏覽器解析HTML內容

客戶端瀏覽器首先解析狀態行,查看代表請求是否成功的狀態代碼。而後解析每個響應頭,響應頭告知如下爲若干字節的HTML文檔和文檔的字符集。客戶端瀏覽器讀取響應數據HTML,根據HTML的語法對其進行格式化,並在瀏覽器窗口中顯示。
例如:在瀏覽器地址欄鍵入URL,按下回車以後會經歷如下流程:

  1. 瀏覽器向 DNS 服務器請求解析該 URL 中的域名所對應的 IP 地址;
  2. 解析出 IP 地址後,根據該 IP 地址和默認端口 80,和服務器創建TCP鏈接;
  3. 瀏覽器發出讀取文件(URL 中域名後面部分對應的文件)的HTTP 請求,該請求報文做爲 TCP 三次握手的第三個報文的數據發送給服務器;
  4. 服務器對瀏覽器請求做出響應,並把對應的 html 文本發送給瀏覽器;
  5. 釋放 TCP鏈接;
  6. 瀏覽器將該 html 文本並顯示內容;   

7、HTTP請求方法

HTTP/1.1協議中共定義了八種方法(也叫「動做」)來以不一樣方式操做指定的資源:

一、GET

向指定的資源發出「顯示」請求。使用GET方法應該只用在讀取數據,而不該當被用於產生「反作用」的操做中,例如在Web Application中。其中一個緣由是GET可能會被網絡蜘蛛等隨意訪問。

二、HEAD

與GET方法同樣,都是向服務器發出指定資源的請求。只不過服務器將不傳回資源的本文部分。它的好處在於,使用這個方法能夠在沒必要傳輸所有內容的狀況下,就能夠獲取其中「關於該資源的信息」(元信息或稱元數據)。

三、POST

向指定資源提交數據,請求服務器進行處理(例如提交表單或者上傳文件)。數據被包含在請求本文中。這個請求可能會建立新的資源或修改現有資源,或兩者皆有。

四、PUT

向指定資源位置上傳其最新內容。

五、DELETE

請求服務器刪除Request-URI所標識的資源。

六、TRACE

回顯服務器收到的請求,主要用於測試或診斷。

七、OPTIONS

這個方法可以使服務器傳回該資源所支持的全部HTTP請求方法。用'*'來代替資源名稱,向Web服務器發送OPTIONS請求,能夠測試服務器功能是否正常運做。

八、CONNECT

HTTP/1.1協議中預留給可以將鏈接改成管道方式的代理服務器。一般用於SSL加密服務器的連接(經由非加密的HTTP代理服務器)。

注意事項:

  1. 方法名稱是區分大小寫的。當某個請求所針對的資源不支持對應的請求方法的時候,服務器應當返回狀態碼405(Method Not Allowed),當服務器不認識或者不支持對應的請求方法的時候,應當返回狀態碼501(Not Implemented)。
  2. HTTP服務器至少應該實現GET和HEAD方法,其餘方法都是可選的。固然,全部的方法支持的實現都應當匹配下述的方法各自的語義定義。此外,除了上述方法,特定的HTTP服務器還可以擴展自定義的方法。例如PATCH(由 RFC 5789 指定的方法)用於將局部修改應用到資源

8、http協議總結

HTTP請求格式

HTTP響應格式

一、簡單快速

客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法經常使用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯繫的類型不一樣。因爲HTTP協議簡單,使得HTTP服務器的程序規模小,於是通訊速度很快。

二、靈活

HTTP容許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。

三、無鏈接

  • 基於TCP/IP:http協議是基於TCP/IP協議之上的應用層協議。
  • 基於請求-響應模式:HTTP協議規定,請求從客戶端發出,最後服務器端響應該請求並 返回。換句話說,確定是先從客戶端開始創建通訊的,服務器端在沒有接收到請求以前不會發送響應。
  • 無狀態保存:HTTP是一種不保存狀態,即無狀態(stateless)協議。HTTP協議 自身不對請求和響應之間的通訊狀態進行保存。也就是說在HTTP這個 級別,協議對於發送過的請求或響應都不作持久化處理。
  • 無鏈接:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。
  • HTTP無鏈接說的是:當某個客戶機在短期屢次請求同一個資源,服務器並不能區別是否已經響應過用戶的請求。 因而咱們每次發送http請求,都須要事先發起一個到服務器的TCP請求,經歷「三次握手」的過程。這針對大流量的的服務器來講,開銷是至關大的。這是http無連接帶來的缺點
  • 針對http無鏈接,人們設計了非持久鏈接和持久鏈接。實際上關於http協議非持久鏈接和持久鏈接是針對tcp協議的。當客戶機/服務器的交互運行於TCP協議上時,應用程序的每一個請求/響應對是經不一樣的TCP鏈接時,則該應用程序使用非持久鏈接,而當應用程序的每一個請求/響應對是經相同的TCP鏈接發送,則該應用程序使用持久鏈接。
  • 非持久鏈接:請求一個HTTP請求/響應須要的總時間=客戶端發出創建鏈接+發生請求報文+服務器傳輸HTML文件的時間
  • 持久鏈接:服務器在發送響應後,保持該TCP鏈接打開。在相同的客戶機與服務器之間的後續請求和響應報文經過相同的鏈接進行傳送。不須要再次創建tcp鏈接

四、無狀態

  • 所謂http是無狀態協議,言外之意是說http協議無法保存客戶機信息,
  • 無狀態的優勢是:在服務器不須要先前信息時它的應答就較快。
  • 無狀態的缺點是:缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳。這樣可能致使每次鏈接傳送的數據量增大
  • 關於http無狀態阻礙了交互式應用程序的實現。好比記錄用戶瀏覽哪些網頁、判斷用戶是否擁有權限訪問等。因而,兩種用於保持HTTP狀態的技術就應運而生了,一個是Cookie,而另外一個則是Session。

五、支持B/S及C/S模式。

import socket

server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(('127.0.0.1',8080))
server.listen(5)


while True:
    conn,client_addr=server.accept()

    request=conn.recv(1024)
    # print(request)
    print(request.decode('utf-8'))

    conn.send(b'HTTP/1.1 200 OK\r\n\r\n<h1>hello</h1>')
    conn.close()
自定義套接字服務端抓取瀏覽器發來的HTTP請求
import socket

server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(('127.0.0.1',8080))
server.listen(5)


while True:
    conn,client_addr=server.accept()

    request=conn.recv(1024)
    # print(request)
    print(request.decode('utf-8'))

    with open('index.html','rb') as f:
        data=f.read()
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n%s' %data)
    conn.close()
從文件中讀取內容發送給瀏覽器

TCP/IP和HTTP的區別

  • TCP/IP協議是傳輸層協議,主要解決數據如何在網絡中傳輸,而HTTP是應用層協議,主要解決如何包裝數據。
  • 在傳輸數據時,能夠只使用(傳輸層)TCP/IP協議,可是那樣的話,若是沒有應用層,便沒法識別數據內容
  • 想要使傳輸的數據有意義,則必須使用到應用層協議,應用層協議有不少,好比HTTP、FTP、TELNET等,也能夠本身定義應用層協議。
  • WEB使用HTTP協議做應用層協議,以封裝HTTP 文本信息,而後使用TCP/IP作傳輸層協議將它發到網絡上。
  • TCP/IP表明傳輸控制協議/網際協議,指的是一系列協議。「IP」表明網際協議,TCP和UDP使用該協議從一個網絡傳送數據包到另外一個網絡。把IP想像成一種高速公路,它容許其它協議在上面行駛並找到到其它電腦的出口。TCP和UDP是高速公路上的「卡車」,它們攜帶的貨物就是像HTTP,文件傳輸協議FTP這樣的協議等。
  • 雖然TCP和UDP都是用來傳輸其餘協議的,它們卻有一個顯著的不一樣:TCP提供有保證的數據傳輸,而UDP不提供。這意味着TCP有一個特殊的機制來確保數據安全的不出錯的從一個端點傳到另外一個端點,而UDP不提供任何這樣的保證。
  • HTTP(超文本傳輸協議)是利用TCP在兩臺電腦(一般是Web服務器和客戶端)之間傳輸信息的協議。客戶端使用Web瀏覽器發起HTTP請求給Web服務器,Web服務器發送被請求的信息給客戶端。
7 應用層 例如HTTPSMTPSNMPFTPTelnetSIPSSHNFSRTSPXMPPWhoisENRP
6 表示層 例如XDRASN.1SMBAFPNCP
5 會話層 例如ASAPTLSSSH、ISO 8327 / CCITT X.22五、RPCNetBIOSASPWinsockBSD sockets
4 傳輸層 例如TCPUDPRTPSCTPSPXATPIL
3 網絡層 例如IPICMPIGMPIPXBGPOSPFRIPIGRPEIGRPARPRARP、 X.25
2 數據鏈路層 例如以太網令牌環HDLC幀中繼ISDNATMIEEE 802.11FDDIPPP
1 物理層 例如線路無線電光纖信鴿

1、HTTP協議的幾個重要概念

  • 1.鏈接(Connection):一個傳輸層的實際環流,它是創建在兩個相互通信的應用程序之間。
  • 2.消息(Message):HTTP通信的基本單位,包括一個結構化的八元組序列並經過鏈接傳輸。
  • 3.請求(Request):一個從客戶端到服務器的請求信息包括應用於資源的方法、資源的標識符和協議的版本號
  • 4.響應(Response):一個從服務器返回的信息包括HTTP協議的版本號、請求的狀態(例如「成功」或「沒找到」)和文檔的MIME類型。
  • 5.資源(Resource):由URI標識的網絡數據對象或服務。
  • 6.實體(Entity):數據資源或來自服務資源的回映的一種特殊表示方法,它可能被包圍在一個請求或響應信息中。一個實體包括實體頭信息和實體的自己內容。
  • 7.客戶機(Client):一個爲發送請求目的而創建鏈接的應用程序。
  • 8.用戶代理
  • (Useragent):初始化一個請求的客戶機。它們是瀏覽器、編輯器或其它用戶工具。
  • 9.服務器(Server):一個接受鏈接並對請求返回信息的應用程序。
  • 10.源服務器(Originserver):是一個給定資源能夠在其上駐留或被建立的服務器。
  • 11.代理(Proxy):一箇中間程序,它能夠充當一個服務器,也能夠充當一個客戶機,爲其它客戶機創建請求。請求是經過可能的翻譯在內部或通過傳遞到其它的服務器中。一個代理在發送請求信息以前,必須解釋而且若是可能重寫它。 代理常常做爲經過防火牆的客戶機端的門戶,代理還能夠做爲一個幫助應用來經過協議處理沒有被用戶代理完成的請求。
  • 12.網關(Gateway):一個做爲其它服務器中間媒介的服務器。與代理不一樣的是,網關接受請求就好象對被請求的資源來講它就是源服務器;發出請求的客戶機並無意識到它在同網關打交道。網關常常做爲經過防火牆的服務器端的門戶,網關還能夠做爲一個協議翻譯器以便存取那些存儲在非HTTP系統中的資源。
  • 13.通道(Tunnel):是做爲兩個鏈接中繼的中介程序。一旦激活,通道便被認爲不屬於HTTP通信,儘管通道多是被一個HTTP請求初始化的。當被中繼的鏈接兩端關閉時,通道便消失。當一個門戶(Portal)必須存在或中介(Intermediary)不能解釋中繼的通信時通道被常用。
  • 14.緩存(Cache):反應信息的局域存儲。

web應用

Web應用程序是一種能夠經過Web訪問的應用程序,用戶只須要有瀏覽器便可訪問應用程序,不須要再安裝其餘軟件。應用程序有兩種模式C/S、B/S。C/S是客戶端/服務器端程序,這類程序通常獨立運行。而B/S是瀏覽器端/服務器端應用程序,這類應用程序通常藉助瀏覽器來運行。WEB應用程序通常是B/S模式。在網絡編程的意義下,瀏覽器是一個socket客戶端,服務器是一個socket服務端。

1、web框架

Web框架(Web framework)是一種開發框架,用來支持動態網站、網絡應用和網絡服務的開發。大多數的web框架提供了一套開發和部署網站的方式,也爲web行爲提供了一套通用的方法。web框架已經實現了不少功能,開發人員使用框架提供的方法而且完成本身的業務邏輯,就能快速開發web應用了。瀏覽器和服務器的是基於HTTP協議進行通訊的。

2、wsgiref模塊

  • 最簡單的Web應用就是先把HTML用文件保存好,用一個現成的HTTP服務器軟件,接收用戶請求,從文件中讀取HTML,返回。
  • 若是要動態生成HTML,就須要把上述步驟本身來實現。不過,接受HTTP請求、解析HTTP請求、發送HTTP響應都是苦力活,若是咱們本身來寫這些底層代碼,還沒開始寫動態HTML呢,就得花個把月去讀HTTP規範。
  • 正確的作法是底層代碼由專門的服務器軟件實現,咱們用Python專一於生成HTML文檔。由於咱們不但願接觸到TCP鏈接、HTTP原始請求和響應格式,因此,須要一個統一的接口協議來實現這樣的服務器軟件,讓咱們專心用Python編寫Web業務。這個接口就是WSGI:Web Server Gateway Interface。而wsgiref模塊就是python基於wsgi協議開發的服務模塊。

3、自定義框架

  • 運行manage.py
  • 瀏覽器輸入:http://127.0.0.1:8889/login/ 訪問

from wsgiref.simple_server import make_server

from app01.views import *
import urls


def routers():

    URLpattern=urls.URLpattern
    return URLpattern


def applications(environ,start_response):

    path=environ.get("PATH_INFO")
    start_response('200 OK', [('Content-Type', 'text/html'),('Charset', 'utf8')])
    urlpattern=routers()
    func=None
    for item in urlpattern:
        if path==item[0]:
            func=item[1]
            break
    if func:
        return [func(environ)]
    else:
        return [b"<h1>404!<h1>"]

if __name__ == '__main__':

    server=make_server("",8889,applications)
    print("server is working...")
    server.serve_forever()
啓動文件manage.py
from app01.views import *


URLpattern = (
    ("/login/", login),
)
urls.py
import pymysql

from urllib.parse import parse_qs


def login(request):

    if request.get("REQUEST_METHOD")=="POST":

        try:
            request_body_size = int(request.get('CONTENT_LENGTH', 0))
        except (ValueError):
            request_body_size = 0

        request_body = request['wsgi.input'].read(request_body_size)
        data = parse_qs(request_body)


        user=data.get(b"user")[0].decode("utf8")
        pwd=data.get(b"pwd")[0].decode("utf8")

        #鏈接數據庫
        conn = pymysql.connect(host='127.0.0.1',port= 3306,user = 'root',passwd='',db='web') # db:庫名
        #建立遊標
        cur = conn.cursor()
        SQL="select * from userinfo WHERE NAME ='%s' AND PASSWORD ='%s'"%(user,pwd)
        cur.execute(SQL)

        if cur.fetchone():

            f=open("templates/backend.html","rb")
            data=f.read()
            data=data.decode("utf8")
            return data.encode("utf8")

        else:
             print("OK456")
             return b"user or pwd is wrong"

    else:
        f = open("templates/login.html", "rb")
        data = f.read()
        f.close()
        return data
views.py
import pymysql
#鏈接數據庫
conn = pymysql.connect(host='127.0.0.1',port= 3306,user = 'root',passwd='',db='web') #db:庫名
#建立遊標
cur = conn.cursor()

sql='''
create table userinfo(
        id INT PRIMARY KEY ,
        name VARCHAR(32) ,
        password VARCHAR(32)
)

'''

cur.execute(sql)

#提交
conn.commit()
#關閉指針對象
cur.close()
#關閉鏈接對象
conn.close()
models.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h4>登陸頁面</h4>
<form action="" method="post">
     用戶名 <input type="text" name="user">
     密碼 <input type="text" name="pwd">
    <input type="submit">
</form>

</body>
</html>
login.html
相關文章
相關標籤/搜索