騷年,渴望力量嗎,http知識,你要的都在這裏

1.HTTP有幾個版本?

HTTP有三個版本,HTTP/0.9 ,HTTP/1.0, HTTP/1.1 ,HTTP/2。前端

2.各個版本的區別改進有哪些?

  • HTTP/0.9

只有一個命令GET,而且服務器只能迴應HTML格式的字符串,不能迴應別的格式。編程

  • HTTP/1.0

除了GET命令,還引入了POST命令和HEAD命令,任何格式的內容均可以發送,除了數據部分,每次通訊都必須包括頭信息(HTTP header),新增功能還包括狀態碼(status code)、多字符集支持、多部分發送(multi-part type)、權限(authorization)、緩存(cache)、內容編碼(content encoding)。TCP鏈接只能發送一個請求,發送數據完畢,鏈接就關閉,若是還要請求其餘資源,就必須再新建一個鏈接,爲了解決這個問題,引入了一個非標準的Connection字段——Connection: keep-alive,Connection: keep-alive,服務器一樣迴應這個字段——Connection: keep-alive瀏覽器

  • HTTP/1.1

引入了持久鏈接(persistent connection),即TCP鏈接默認不關閉,能夠被多個請求複用,不用聲明Connection: keep-alive。同時還引入了管道機制(pipelining),即在同一個TCP鏈接裏面,客戶端能夠同時發送多個請求,可是服務器仍是按照順序,先回應A請求,完成後再回應B請求。同時1.1版還新增了許多動詞方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。特別的是頭信息確定是文本(ASCII編碼),而數據體能夠是文本,也能夠是二進制。緩存

  • HTTP/2

HTTP/2是一個完全的二進制協議,頭信息和數據體都是二進制,而且統稱爲"幀"(frame):頭信息幀和數據幀。 在頭信息還引入了頭信息壓縮機制(header compression)。一方面,頭信息使用gzip或compress壓縮後再發送 HTTP/2 複用TCP鏈接,在一個鏈接裏,客戶端和瀏覽器均可以同時發送多個請求或迴應,並且不用按照順序一一對應,這樣就避免了"隊頭堵塞"。bash

3.新增的狀態碼有哪些?各表明什麼意思?

  • 2開頭的:

200確定是請求成功,返回數據。
201 (已建立) 請求成功而且服務器建立了新的資源。
202 (已接受) 服務器已接受請求,但還沒有處理。
203 (非受權信息) 服務器已成功處理了請求,但返回的信息可能來自另外一來源。
204 (無內容) 服務器成功處理了請求,但沒有返回任何內容。
205 (重置內容) 服務器成功處理了請求,但沒有返回任何內容。
206 (部份內容) 服務器成功處理了部分 GET 請求。服務器

  • 3開頭的:

3xx (重定向) 表示要完成請求,須要進一步操做。 一般,這些狀態代碼用來重定向。
300 (多種選擇) 針對請求,服務器可執行多種操做。 服務器可根據請求者 (user agent) 選擇一項操做,或提供操做列表供請求者選擇。
301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。
302 (臨時移動) 服務器目前從不一樣位置的網頁響應請求,但請求者應繼續使用原有位置來進行之後的請求。
303 (查看其餘位置) 請求者應當對不一樣的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。
304 (未修改) 自從上次請求後,請求的網頁未修改過。服務器返回此響應時,不會返回網頁內容。客戶端一般會緩存訪問過的資源,經過提供一個頭信息指出客戶端但願只返回在指定日期以後修改的資源 。
305 (使用代理) 請求者只能使用代理訪問請求的網頁。 若是服務器返回此響應,還表示請求者應使用代理。
307 (臨時重定向) 服務器目前從不一樣位置的網頁響應請求,但請求者應繼續使用原有位置來進行之後的請求。cookie

  • 4開頭的:

4xx(請求錯誤) 這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。 400 (錯誤請求) 服務器不理解請求的語法。
401 (未受權) 請求要求身份驗證。 對於須要登陸的網頁,服務器可能返回此響應。
403 (禁止) 服務器拒絕請求。
404 (未找到) 服務器找不到請求的網頁。
405 (方法禁用) 禁用請求中指定的方法。
406 (不接受) 沒法使用請求的內容特性響應請求的網頁。
407 (須要代理受權) 此狀態代碼與 401(未受權)相似,但指定請求者應當受權使用代理。
408 (請求超時) 服務器等候請求時發生超時。
409 (衝突) 服務器在完成請求時發生衝突。 服務器必須在響應中包含有關衝突的信息。
410 (已刪除) 若是請求的資源已永久刪除,服務器就會返回此響應。
411 (須要有效長度) 服務器不接受不含有效內容長度標頭字段的請求。
412 (未知足前提條件) 服務器未知足請求者在請求中設置的其中一個前提條件。
413 (請求實體過大) 服務器沒法處理請求,由於請求實體過大,超出服務器的處理能力。
414 (請求的 URI 過長) 請求的 URI(一般爲網址)過長,服務器沒法處理。
415 (不支持的媒體類型) 請求的格式不受請求頁面的支持。
416 (請求範圍不符合要求) 若是頁面沒法提供請求的範圍,則服務器會返回此狀態代碼。
417 (未知足指望值) 服務器未知足"指望"請求標頭字段的要求。網絡

  • 5開頭的:

5xx(服務器錯誤)這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤多是服務器自己的錯誤,而不是請求出錯。 500 (服務器內部錯誤) 服務器遇到錯誤,沒法完成請求。
501 (還沒有實施) 服務器不具有完成請求的功能。 例如,服務器沒法識別請求方法時可能會返回此代碼。
502 (錯誤網關) 服務器做爲網關或代理,從上游服務器收到無效響應。
503 (服務不可用) 服務器目前沒法使用(因爲超載或停機維護)。 一般,這只是暫時狀態。
504 (網關超時) 服務器做爲網關或代理,可是沒有及時從上游服務器收到請求。
505 (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。
(前端這個時候就能夠甩鍋了,不是我這邊的問題)socket

4. 何時會出現304狀態碼?

若是要知道何時出現304狀態碼,那麼咱們就要從緩存機制講起了。tcp

經過在這裏看,知道本身日常使用的網頁請求文件是怎麼樣緩存的

下面的圖片標誌有誤,請求頭跟返回頭的標誌位置要換過來

緩存機制分爲:強制緩存跟協商緩存,以及在進行協商緩存前的啓發式緩存,其中強制緩存優先級高於協商緩存.

  • 強制緩存

對於強制緩存,服務器響應的header中會用兩個字段來代表 Expires和Cache-Control。

Expires

Exprires的值爲服務端返回的數據到期時間。當再次請求時的請求時間小於返回的此時間,則直接使用緩存數據 Expires是HTTP/1.0中的定義緩存的字段,它規定了緩存過時的一個絕對時間,Expires是HTTP1.0的產物,故如今大多數使用Cache-Control替代。Expires有一個很大的弊端,就是它返回的是服務器的時間,但判斷的時候用的倒是客戶端的時間,這就致使Expires很被動,由於用戶有可能改變客戶端的時間,致使緩存時間判斷出錯,這也是引入Cache-Control:max-age指令的緣由之一。

Cache-Control

Cache-Control是HTTP/1.1定義的關於緩存的字段,其中Cache-Control的max-age屬性規定了緩存過時的一個相對時間。優先級上固然是版本高的優先了,max-age > Expires。

例如:當cache-Control:max-age=300(以秒爲單位)時,則表明在這個請求正確返回時間(瀏覽器也會記錄下來)的5分鐘內再次加載資源,就會命中強緩存,這個時候瀏覽器請求會返回200成功。

若是是在Chrome瀏覽器會返回灰色200(from disk cache)或是200 OK (from memory cache)

若是是在Firefox瀏覽器會返回一個灰色的200狀態碼。

這裏介紹一下memory cache 跟disk cache的區別

先打開個人博客,打開network看一下加載的資源

from memory cache 表明使用內存中的緩存

from disk cache 則表明使用的是硬盤中的緩存

瀏覽器讀取緩存的順序爲memory –> disk。Chrome會根據本地內存的使用率來決定緩存存放在哪,若是內存使用率低,放在磁盤裏面,內存的使用率很高會暫時放在內存裏面。這就能夠比較合理的解釋了爲何同一個資源有時是from memory cache有時是from disk cache的問題了。

固然 cache-control不僅是隻有max-age這個屬性,還有如下經常使用的幾個屬性:

public:全部內容都將被緩存(客戶端和代理服務器均可緩存)。具體來講響應可被任何中間節點緩存,如 Browser <-- proxy1 <-- proxy2 <-- Server,中間的proxy能夠緩存資源,好比下次再請求同一資源proxy1直接把本身緩存的東西給 Browser 而再也不向proxy2要。

private:Cache-Control的默認取值,全部內容只有客戶端能夠緩存。具體來講,表示中間節點不容許緩存,對於Browser <-- proxy1 <-- proxy2 <-- Server,proxy 會老老實實把Server 返回的數據發送給proxy1,本身不緩存任何數據。當下次Browser再次請求時proxy會作好請求轉發而不是自做主張給Browser本身緩存的數據。

no-cache:客戶端緩存內容,是否使用緩存則須要通過協商緩存來驗證決定。表示不使用 Cache-Control的緩存控制方式作前置驗證,而是使用 Etag 或者Last-Modified字段來控制緩存。須要注意的是,no-cache這個名字有一點誤導。設置了no-cache以後,並非說瀏覽器就再也不緩存數據,只是瀏覽器在使用緩存數據時,須要先確認一下數據是否還跟服務器保持一致。

簡單來講:就是直接進入協商緩存,不使用expire跟cache-control的max-age驗證,直接向服務端請求確認

no-store:全部內容都不會被緩存,即不使用強制緩存,也不使用協商緩存

max-age:max-age=xxx (xxx is numeric)表示緩存內容將在xxx秒後失效,表示資源在本地緩存的最大時間,

s-maxage(單位爲s):同max-age,只用於共享緩存(好比CDN緩存)。好比當s-maxage=60時,在這60秒中,即便更新了CDN的內容,瀏覽器也不會進行請求。max-age用於普通緩存,而s-maxage用於代理緩存。s-maxage的優先級高於max-age。若是存在s-maxage,則會覆蓋掉max-age和Expires header。

  • 協商緩存

當expire過時而且max-age(s-max-age)超時了 ,或者直接設置no-cache了,那麼會使用協商緩存。

經過如下這兩個字段:If-None-Match(只能精確到秒)和If-Modified-Since(精確到毫秒) 進行協商判斷是否使用緩存

If-None-Match(只要修改文件,資源惟一標識就會發生變化)和If-Modified-Since(只能精確到秒)ETag的優先級比Last-modified更高 ,若是有Etag,那麼就比較Etag,不比較Last-modified,若是Etag沒有發生改變,那麼直接返回304 狀態碼使用緩存,若是Etag改變了,則返回304; 若是Etag不存在,則比較Last-modified,若是Last-modified沒有改變 則返回304,告訴瀏覽器繼續使用緩存,若是Last-modified改變了,那麼返回狀態碼200返回新內容

既然已經有Last-modified了,那麼爲啥還要有Etag呢,緣由就是:

Etag的出現主要是爲了解決幾個Last-Modified比較難解決的問題:

  1. Last-Modified標註的最後修改只能精確到秒級,若是某些文件在1秒鐘之內,被修改屢次的話,它將不能準確標註文件的修改時間。
  2. 若是某些文件會被按期生成,當有時內容並無任何變化,但Last-Modified卻改變了,致使文件無法使用緩存。
  3. 有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形。

可是使用Etag也不是必須的,由於使用Etag有可能會帶來性能浪費的問題

一般狀況下,ETag更相似於資源指紋(fingerprints),若是資源發生變化了就會生成一個新的指紋,這樣能夠快速的比較資源的變化。在服務器端實現中,不少狀況下並不會用哈希來計算ETag,這會嚴重浪費服務器端資源,不少網站默認是禁用ETag的。有些狀況下,能夠把ETag退化,好比經過資源的版本或者修改時間Last-modified來生成ETag,因此有來Last-modified爲標準的Etag,其實就不必再使用Last-modified來,除非是不存在Etag,才使用Last-modified來進行判斷。

在返回的響應頭是:

ETag: "5be7d50a-30e"
Last-Modified: Sun, 11 Nov 2018 07:06:50 GMT
複製代碼

在發送的請求頭是:

If-Modified-Since: Sun, 11 Nov 2018 07:06:50 GMT
If-None-Match: W/"5be7d50a-30e" 
複製代碼

服務器經過這兩個字段來判斷資源是否有修改,若是有修改則返回狀態碼200和新的內容,該咋處理就咋處理(至關於首次訪問這個文件了)

若是沒有修改,返回狀態碼304,若是瀏覽器發現返回304,因而知道了本地緩存雖然過時但仍然能夠用,因而加載本地緩存。而後根據新的返回的響應頭來設置緩存。

這個就能回答到上面的問題,304狀態碼是怎麼來的:因爲協商請求,對比服務器的內容跟時間未發生改變,返回304狀態碼,瀏覽器繼續使用本地緩存。

  • 啓發式緩存

啓發式緩存階段是在沒有強制緩存時候,進入協商緩存前的一個階段,是瀏覽器使用的默認緩存協議

Cache-Control: public
Date:Tue, 28 Nov 2018 12:26:41 GMT
Last-Modified: Sun, 11 Nov 2018 07:06:50 GMT
Vary:Accept-Encoding
複製代碼

根據響應頭中2個時間字段 Date 和 Last-Modified 之間的時間差值,取其值的10%做爲緩存時間週期。若是請求時間在 從Last-Modified算起加上這個時間週期 的時間之內,則使用默認緩存,若是超過,則進入協商緩存。

5. 總結下跟緩存有關的首部字段以及各類關係?

  • Pragma HTTP1.0時的遺留字段,當值爲"no-cache"時強制驗證緩存
  • ETag 服務器生成資源的惟一標識,由服務端返回給客戶端
  • Last-Modified 服務器資源的最後一次的修改時間,由服務端返回給客戶端, Last-Modified有幾個缺點:無法準確的判斷資源是否真的修改了,好比某個文件在1秒內頻繁更改了屢次,根據Last-Modified的時間(單位是秒)是判斷不出來的,再好比,某個資源只是修改了,但實際內容並無發生變化,Last-Modified也沒法判斷出來,所以在HTTP/1.1中還推出了ETag這個字段,只要修改了文件,Etag資源惟一標識就會發生變化。
  • If-None-Match 客戶端存下的服務器資源的惟一表示,由客戶端發送給服務端
  • If-Modified-Since 客戶端存下的服務器資源的最後一次的修改時間,由客戶端發送給服務端
  • vary Vary用來作什麼的呢?試想這麼一個場景:在某個網頁中網站提供給移動端的內容是不一樣的,怎麼讓緩存服務器區分移動端和PC端呢?不知道你是否注意,瀏覽器在每次請求都會攜帶UA字段來代表來源,因此咱們能夠利用User-Agent字段來區分不一樣的客戶端,用法以下:
Vary: User-Agent
複製代碼

好比,源服務器啓用了gzip壓縮,但用戶使用了比較舊的瀏覽器,不支持壓縮,緩存服務器如何返回?就能夠這麼設定:

Vary: Accept-Encoding
複製代碼
  • Age 資源在緩存代理中存貯的時長(取決於max-age和s-maxage的大小) 這個字段說的是資源在緩存服務器存在的時長,前面也說了Cache-Control: max-age=[秒]就是Age的最大值。 這個字段存在的意義是什麼呢?用來區分請求的資源來自源服務器仍是緩存服務器的緩存的。 須要結合另外一個字段來進行判斷,就是Date,Date是報文建立的時間。
Accept-Ranges: bytes
Age: 1016859
Cache-Control: max-age=2592000
Content-Length: 14119
Content-Type: image/png
Date: Fri, 01 Dec 2017 12:27:25 GMT
ETag: "5912bfd0-3727"
Expires: Tue, 19 Dec 2017 17:59:46 GMT
Last-Modified: Wed, 10 May 2017 07:22:56 GMT
Ohc-Response-Time: 1 0 0 0 0 0
Server: bfe/1.0.8.13-sslpool-patch
複製代碼

咱們能夠看到Age=1016859,說明這個資源已經在緩存服務器存在了1016859秒。若是文件被修改或替換,Age會從新由0開始累計。

Age消息頭的值一般接近於0。表示此消息對象剛剛從原始服務器獲取不久;其餘的值則是表示代理服務器當前的系統時間與此應答消息中的通用消息頭 Date的值之差。

靜態資源Age + 靜態資源Date = 原服務端Date
複製代碼

6.Tcp的三次握手跟四次揮手是怎麼回事?

TCP報文格式:

  • (1)32位序號:seq序號,佔32位,用來標識從TCP源端向目的端發送的字節流,發起方發送數據時對此進行標記。
  • (2)確認序號:ack序號,佔32位,只有ACK標誌位爲1時,確認序號字段纔有效,Ack=Seq+1。
  • (3)標誌位:共6個,即URG、ACK、PSH、RST、SYN、FIN等,具體含義以下:(A)URG:緊急指針(urgent pointer)有效。(B)ACK:確認序號有效。(C)PSH:接收方應該儘快將這個報文交給應用層。(D)RST:重置鏈接。(E)SYN:發起一個新鏈接。(F)FIN:釋放一個鏈接

**注意:**確認包的ack序號跟標誌位的ACK不是指同一個,前者是ack序列號 ack=seq+1,後者是標誌位的ack位,爲1 時候表示確認序號有效。

三次握手

  • 第一次握手

客戶端發送tcp請求包(標誌位SYN爲1,表示發起一個新鏈接。seq=x,初始序號x,保存在包頭的序列號(Sequence Number)字段裏)也成爲ISN),客戶端進入SYN-SENT階段,而後服務器監聽到請求連接,被動打開連接。

  • 第二次握手

服務端接受到客戶端發送過來的tcp請求包以後,解析報文以後,服務器向客戶端發回確認包(標誌位ACK=1,表示確認序號有效。標誌位SYN爲1,表示發起一個新鏈接。ack=x+1,確認序號ack設置爲x+1 便是第一次握手請求包裏面的seq(ISN)加上1。而後確認包的序列號(seq)設置爲y,返回給客戶端)應答,服務端進入SYN-RCVD狀態。

  • 第三次握手

客戶端接受到服務端返回的確認包,解析報文,設置ack=ISN+1=y+1,seq=上一次返回的確認包的ack,而後發送確認包。

發送的確認包,標誌位SYN爲0,表示不用發起新鏈接,由於原先第一次握手已經創建了。標誌位ACK爲1,表示確認序號有效。確認包的確認序號ack=y+1,便是第二次握手確認包裏面的序號seq加上1。這次握手返回的確認包 ,序列號(seq)設置爲x+1,便是上一次確認包的ack確認序號,返回給服務端,進入ESTAB-LISHED狀態,服務端收到以後,進入ESTAB-LISHED狀態,雙方連接創建,開始數據傳送

SYN攻擊

SYN攻擊在三次握手過程當中,服務器發送SYN-ACK以後,收到客戶端的ACK以前的TCP鏈接稱爲半鏈接(half-open connect).此時服務器處於Syn_RECV狀態.當收到ACK後,服務器轉入ESTABLISHED狀態.

Syn攻擊就是 攻擊客戶端 在短期內僞造大量不存在的IP地址,向服務器不斷地發送syn包,服務器回覆確認包,並等待客戶的確認,因爲源地址是不存在的,服務器須要不斷的重發直 至超時,這些僞造的SYN包將長時間佔用未鏈接隊列,正常的SYN請求被丟棄,目標系統運行緩慢,嚴重者引發網絡堵塞甚至系統癱瘓。

Syn攻擊是一個典型的DDOS攻擊。檢測SYN攻擊很是的方便,當你在服務器上看到大量的半鏈接狀態時,特別是源IP地址是隨機的,基本上能夠判定這是一次SYN攻擊.在Linux下能夠以下命令檢測是否被Syn攻擊netstat -n -p TCP | grep SYN_RECV通常較新的TCP/IP協議棧都對這一過程進行修正來防範Syn攻擊,修改tcp協議實現。主要方法有SynAttackProtect保護機制、SYN cookies技術、增長最大半鏈接和縮短超時時間等.可是不能徹底防範syn攻擊。

四次揮手

TCP的鏈接的拆除須要發送四個包,所以稱爲四次揮手(four-way handshake)。客戶端或服務器都可主動發起揮手動做,在socket編程中,任何一方執行close()操做便可產生揮手操做。

假設Client端發起中斷鏈接請求,也就是發送FIN報文。

Server端接到FIN報文後,clinet的意思是"我Client端沒有數據要發給你了,可是若是你還有數據沒有發送完成,則沒必要急着關閉Socket,能夠繼續發送數據。"

因此Server先發送ACK,告訴Client端,"你的請求我收到了,我知道你沒東西傳給我了,可是我這邊還沒準備好,請繼續你等個人消息"。

這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。

此時Server有可能向client的傳輸數據還沒結束,當Server端肯定數據已發送完成,則向Client端發送FIN報文,告訴Client端"好了,我這邊數據發完了,準備好關閉鏈接了"。Client端收到FIN報文後,就知道能夠關閉鏈接了,可是他仍是不相信網絡,怕Server端不知道要關閉,因此發送ACK後進入TIME_WAIT狀態,若是Server端沒有收到ACK則會發起重傳。

Server端收到ACK後,"就知道能夠斷開鏈接了"。Client端等待了2MSL(2個報文傳送週期) 2個報文週期的計算:若是第四次握手的確認信息丟失,服務器將會從新發送第三次握手的斷開鏈接的信號,而服務器發覺丟包(假設有確認信息的話要等待一個報文傳輸週期)與從新發送的斷開鏈接到達主機的時間(一個報文傳輸週期)正好爲 2 個報文傳輸週期。 2個報文傳輸週期以後依然沒有收到回覆,則證實Server端已正常關閉,那好,我Client端也能夠關閉鏈接了。Ok,TCP鏈接就這樣關閉了!

相關文章
相關標籤/搜索