總綱:前端面試知識點大全
目錄
2.Long-Polling、Websockets 和 Server-Sent Event
2.3 HTML5 Server Sent Events (SSE) / EventSource,不是http2.0中的服務器推送
4.1 強制緩存:Expires(http 1.0)/Cache-Control(http1.1)
10.1 長連接(不會永久保持連接,而是保持一段時間,在不同服務器軟件中可以設置)
1.爲什麼傳統上利用多個域名來提供網站資源會更有效
1.1 常規原因
1) CDN緩存更方便。
2) 突破瀏覽器併發限制。
3) Cookie減少, 節省帶寬,尤其是上行帶寬 一般比下行要慢。
1.2 非常規原因
1) 對於UGC的內容和主站隔離,防止不必要的安全問題。
正是這個原因要求用戶內容的域名必須不是自己主站的子域名,而是一個完全獨立的第三方域名。
2) 數據做了劃分,甚至切到了不同的物理集羣,通過子域名來分流比較省事. 這個可能被用的不多。
1.3 具體細說
1. 靜態內容和動態內容分服務器存放,使用不同的服務器處理請求。處理動態內容的只處理動態內容,不處理別的,提高效率,這樣使得CDN(內容分發網絡)緩存更方便
2、 突破瀏覽器併發限制 (你隨便挑一個 G家的 url: https://lh4.googleusercontent.com/- si4dh2myPWk/T81YkSi__AI/AAAAAAAAQ5o/LlwbBRpp58Q/w497-h373/IMG_20120603_163233.jpg, 把前面的 lh4換成 lh3,lh6 啥的,都照樣能夠訪問,像地圖之類的需要大量併發下載圖片的站點,這個非常重要。)
3、跨域不會傳cookie,節省寬帶;舉例說一下:
twitter 的主站 http://twitter.com ,用戶的每次訪問,都會帶上自己的cookie ,挺大的。假如twitter 的圖片放在主站域名下,那麼用戶每次訪問圖片時,request header 裏就會帶有自己的cookie ,header 裏的cookie 還不能壓縮,而圖片是不需要知道用戶的cookie 的,所以這部分帶寬就白白浪費了。
寫主站程序時,set-cookie 也不要set 到圖片的域名上。
在小流量的網站,這個cookie 其實節省不了多少帶寬,當流量如facebook twitter 時,節省下來就很可觀了。
2.Long-Polling、Websockets 和 Server-Sent Event
2.1 AJAX Polling,普通輪詢
1. 客戶端使用普通的http方式向服務器端請求網頁
2. 客戶端執行網頁中的JavaScript輪詢腳本,定期循環的向服務器發送請求(例如每5秒發送一次請求),獲取信息
3. 服務器對每次請求作出響應,並返回相應信息,就像正常的http請求一樣
2.2 AJAX Long-Polling
1. 客戶端使用普通的http方式向服務器端請求網頁
2. 客戶端執行網頁中的JavaScript腳本,向服務器發送數據、請求信息
3. 服務器並不是立即就對客戶端的請求作出響應,而是等待有效的更新
4. 當信息是有效的更新時,服務器纔會把數據推送給客戶端
5. 當客戶端接收到服務器的通知時,立即會發送一個新的請求,進入到下一次的輪詢
2.3 HTML5 Server Sent Events (SSE) / EventSource,不是http2.0中的服務器推送
原理:服務器向客戶端聲明,接下來要發送的是流信息(streaming),這樣客戶端以爲發送的不是一次性的數據包,而是一個數據流,會連續不斷地發送過來,所以不會關閉連接。
單向通道,只能服務器向客戶端發送數據
1. 客戶端使用普通的http方式向服務器端請求網頁
2. 客戶端執行網頁中的JavaScript腳本,與服務器之間建立了一個連接
3. 當服務器端有有效的更新時,會發送一個事件到客戶端
4. 服務器到客戶端數據的實時推送,大多數內容是你需要的:
i. 你需要一臺可以做Event Loop的服務器
ii. 不允許跨域的連接
iii. 如果你覺得這些還不夠,想要了解更多,可以參考下面的文件和手冊
2.4 HTML5 Websockets:
- 客戶端使用普通的http方式向服務器端請求網頁(upgrade: websocket)
- 客戶端執行網頁中的JavaScript腳本,與服務器之間建立了一個連接
- 服務器和客戶端之間,可以雙向的發送有效數據到對方
-
- 服務器可以實時的發送數據到客戶端,同時客戶端也可以實時的發送數據到服務器
- 你需要一臺可以做Event Loop的服務器
- 使用 WebSockets 允許跨域的建立連接
- 它同樣支持第三方的websocket主機服務器,例如Pusher或者其它。這樣你只需要關心客戶端的實現 ,降低了開發難度。
2.5 總結
瀏覽器兼容性
Long-polling支持大多數當前的瀏覽器
Server-Sent Events支持Chrome9+、Firefox6+、Opera11+、Safari5+
Chrome14、Firefox7支持最新的hybi-10協議,Firefox6支持hybi-07.
服務器負載
Long-polling佔一小部分CPU資源,但是創建空的進程將浪費系統的內存
Server-Sent Events工作的方式有很多,除非Server-Sent Events不必在每一次響應發出後都關閉連接。
WebSockets,服務器只需要一個進程處理所有的請求,沒有循環,不必爲每個客戶端都分配cpu和內存。
客戶端負載
Long-polling取決於實現方式,但終究是一個異步的方式
Server-Sent Events採用瀏覽器的內置的實現方式,只花費很少的一部分資源。
WebSockets跟Server-Sent Events一樣,採用瀏覽器的內置的實現方式,只花費很少的一部分資源。
時間線
Long-polling接近實時,但是發送新的請求和發送相應會有一定的時延。
Server-Sent Events默認延時3秒,但是可以調整。
WebSockets真正的實時
實現方式複雜度
Long-polling實現起來非常簡單
Server-Sent Events甚至比Long-polling更簡單
需要一個WebSockets服務器處理事件,並開放一個端口
3.常見的請求頭和響應頭
可以學習菜鳥教程:http://www.runoob.com/http/http-header-fields.html
4.和緩存有關的HTTP首部字段
參考鏈接https://segmentfault.com/a/1190000010690320
4.1 強制緩存:Expires(http 1.0)/Cache-Control(http1.1)
1)Expires
Expires的值爲服務端返回的到期時間,在響應http請求時告訴瀏覽器在過期時間前瀏覽器可以直接從瀏覽器緩存取數據,而無需再次請求。不過Expires 是HTTP 1.0的東西,現在默認瀏覽器均默認使用HTTP 1.1,所以它的作用基本忽略。Expires 的一個缺點就是,返回的到期時間是服務器端的時間,這樣存在一個問題,比較的時間是客戶端本地設置的時間,所以有可能會導致差錯,所以在HTTP 1.1版開始,使用Cache-Control替代。
Expires: Thu, 01 Dec 1994 16:00:00 GMT (必須是GMT格式)
如果把它設置爲-1,則表示立即過期
2)Cache-Control(優先級比expires高,會覆蓋)
用於定義所有的緩存機制都必須遵循的緩存指示,這些指示是一些特定的指令,包括public、private、no-cache(表示可以存儲,但在重新驗正其有效性之前不能用於響應客戶端請求)、no-store、max-age、s-maxage以及must-revalidate等;Cache-Control中設定的時間會覆蓋Expires中指定的時間;
3)max-age和expires設置緩存時間的區別
max-age是HTTP/1.1中,他是指我們的web中的文件被用戶訪問(請求)後的存活時間,是個相對的值,相對Request_time(請求時間).
例如:A.html 用戶請求時間是18:00,max-age設置的是600的話,相當18:00+600秒過期,也就是相對18:00的時間後面600秒後過期.默認的max-age是由Expires算出來的.
而expires是絕對時間,是基於服務器的時間作爲標準。
4.2 協商緩存
1)Last-Modified/If-Modified-Since
Last-Modified:
服務器在響應請求時,告訴瀏覽器資源的最後修改時間。
If-Modified-Since:
再次請求服務器時,通過此字段通知服務器上次請求時,服務器返回的資源最後修改時間。
服務器收到請求後發現有頭If-Modified-Since 則與被請求資源的最後修改時間進行比對。
若資源的最後修改時間大於If-Modified-Since,說明資源又被改動過,則響應整片資源內容,返回狀態碼200;
若資源的最後修改時間小於或等於If-Modified-Since,說明資源無新修改,則響應HTTP 304,告知瀏覽器繼續使用所保存的cache。
2)Etag/If-None-Match(優先級高於Last-Modified/If-Modified-Since)
Etag:
服務器資源的唯一標識符, 瀏覽器可以根據ETag值緩存數據, 節省帶寬. 如果資源已經改變, etag可以幫助防止同步更新資源的相互覆蓋. ETag 優先級比 Last-Modified 高.
If-None-Match:
再次請求服務器時,通過此字段通知服務器客戶段緩存數據的唯一標識。
服務器收到請求後發現有頭If-None-Match 則與被請求資源的唯一標識進行比對,
不同,說明資源又被改動過,則響應整片資源內容,返回狀態碼200;
相同,說明資源無新修改,則響應HTTP 304,告知瀏覽器繼續使用所保存的cache。
4.3 用戶操作對緩存的影響
4.4 不能緩存的請求:
1、不能被緩存的請求HTTP 信息頭中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0 等告訴瀏覽器不用緩存的請求
2、需要根據Cookie,認證信息等決定輸入內容的動態請求是不能被緩存的
3、經過HTTPS安全加密的請求(有人也經過測試發現,ie 其實在頭部加入 Cache-Control:max-age 信息,firefox 在頭部加入 Cache-Control:Public 之後,能夠對HTTPS的資源進行緩存)
4、HTTP 響應頭中不包含 Last-Modified/Etag,也不包含 Cache-Control/Expires 的請求無法被緩存
5、目前瀏覽器的實現是不會對POST請求的響應做緩存的(從語義上來說也不應該),並且規範中也規定了返回狀態碼不允許是304。不過這並不表示POST的響應不能被緩存,根據RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content中描述的,如果在POST請求對應的響應中包含Freshness相關信息的話,這次響應也是可以被緩存,具體可以參考上面的那個鏈接。
5.GET和POST請求的區別
5.1 用途
GET一般用於獲取/查詢資源信息
POST一般用於更新資源信息,向服務器傳送數據
5.2 區別
1)傳參方式
GET可以通過URL直接傳參;
兩者都可以通過body傳參;
2)長度
1. header和body都沒有對長度的限制;
2. URL的長度受到部分早期瀏覽器的限制;
3. URL的長度還可能受到服務器的限制,由於URL的實際超長或者設定其Content-Length較大值會引起服務器最大併發數下降或者資源空耗;
4. 2和3間接限定了URL方式發起GET方法的長度;
3) 安全性
1. GET不會修改服務端數據,POST可以修改數據
2. URL方式發起GET請求,參數會明文暴露
3. 使用GET提交數據還可能會造成Cross-site request forgery攻擊
4. 本質上安全性無區別
5.3 在以下情況中,請使用 POST 請求:
1. 無法使用緩存文件(更新服務器上的文件或數據庫)
2. 向服務器發送大量數據(POST 沒有數據量限制)
3. 發送包含未知字符的用戶輸入時,POST 比 GET 更穩定也更可靠
5.4 補充(兩者的區別)
1、get參數通過url傳遞,post放在request body中。
2、get請求在url中傳遞的參數是有長度限制的(2k,根據瀏覽器的限制),而post沒有。
3、get比post更不安全,因爲參數直接暴露在url中,所以不能用來傳遞敏感信息。
4、get請求只能進行url編碼,而post支持多種編碼方式
5、get請求會瀏覽器主動cache,而post請求一般不做緩存。
6、get請求參數會被完整保留在瀏覽歷史記錄裏,而post中的參數不會被保留。
7、GET和POST本質上就是TCP鏈接,並無差別。但是由於HTTP的規定和瀏覽器/服務器的限制,導致他們在應用過程中體現出一些不同。
8、GET產生一個TCP數據包;POST產生兩個TCP數據包。
9、對於GET方式的請求,瀏覽器會把http header和data一併發送出去,服務器響應200(返回數據);而對於POST,瀏覽器先發送header,服務器響應100 continue,瀏覽器再發送data,服務器響應200 ok(返回數據)。(這也是第8條的原因)
表單POST支持的傳輸編碼格式(content-type),即enctype屬性的值
1、applicaiton/x-www-form-urlencoded (默認)
以URL編碼後的字符形式,例如:title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
2、multipart/form-data
表單提交常用
3、text/plain(不編碼,title=test&sub=1)
6.HTTP method
OPTIONS:返回服務器針對特定資源所支持的HTTP請求方法。也可以利用向Web服務器發送'*'的請求來測試服務器的功能性。
HEAD:向服務器索要與GET請求相一致的響應,只不過響應體將不會被返回。這一方法可以在不必傳輸整個響應內容的情況下,就可以獲取包含在響應消息頭中的元信息。
GET:向特定的資源發出請求。
POST:向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的創建和/或已有資源的修改。
PUT:向指定資源位置上傳其最新內容。
DELETE:請求服務器刪除Request-URI所標識的資源。
TRACE:回顯服務器收到的請求,主要用於測試或診斷。 追蹤路徑
CONNECT:HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務器。
7.HTTP狀態碼
參考我的個人博客:https://blog.csdn.net/sinat_36521655/article/details/79562358
8.https 加密過程
https是在http基礎上添加了一層ssl(安全套接字層)或者tls(傳輸層安全協議),在TCP於http之間。HTTPS在HTTP的基礎上加入了SSL協議,SSL依靠證書來驗證服務器的身份,併爲瀏覽器和服務器之間的通信加密。
1. 客戶端發起HTTPS請求
2. 服務端的配置
採用HTTPS協議的服務器必須要有一套數字證書,可以是自己製作或者CA證書。區別就是自己頒發的證書需要客戶端驗證通過,纔可以繼續訪問,而使用CA證書則不會彈出提示頁面。這套證書其實就是一對公鑰和私鑰。公鑰給別人加密使用,私鑰給自己解密使用。
3. 傳送證書(公鑰)
這個證書其實就是公鑰,只是包含了很多信息,如證書的頒發機構,過期時間等。
4. 客戶端解析證書
這部分工作是由客戶端的TLS來完成的,首先會驗證公鑰是否有效,比如頒發機構,過期時間等,如果發現異常,則會彈出一個警告框,提示證書存在問題。如果證書沒有問題,那麼就生成一個隨即值,然後用證書對該隨機值進行加密。
5. 傳送加密信息
這部分傳送的是用證書加密後的隨機值,目的就是讓服務端得到這個隨機值,以後客戶端和服務端的通信就可以通過這個隨機值來進行加密解密了。
6. 服務段解密信息
服務端用私鑰解密後,得到了客戶端傳過來的隨機值(私鑰),然後把內容通過該值進行對稱加密。所謂對稱加密就是,將信息和私鑰通過某種算法混合在一起,這樣除非知道私鑰,不然無法獲取內容,而正好客戶端和服務端都知道這個私鑰,所以只要加密算法夠彪悍,私鑰夠複雜,數據就夠安全。
7. 傳輸加密後的信息
這部分信息是服務段用私鑰加密後的信息,可以在客戶端被還原。
8. 客戶端解密信息
客戶端用之前生成的私鑰解密服務段傳過來的信息,於是獲取瞭解密後的內容。
PS: 整個握手過程第三方即使監聽到了數據,也束手無策。
9.http2新特性
9.1 多路複用(一個域只需要一個TCP連接)
同一個連接併發處理多個請求,而且併發請求數量比HTTP1.1大了好幾個量級。
9.2 二進制分幀
在應用層和傳輸層之間增加二進制分幀層,自動將header和body部分區分開。在不改變http 1.x的語義、語法、狀態碼等的情況下,改進傳輸性能
9.3 頭部壓縮
http2考慮頭部信息又是變化並不頻繁,所以在server端做一個緩存,這就是HPACK壓縮方式
(1)傳輸的value會經過哈夫曼編碼來節省資源
(2)爲了server和client同步,兩邊都需要保留一份Header List,並且每次發送請求時,都會檢查更新。(所以第一次發送的內容爲header list)
9.4 服務端推送
服務器對客戶端的一個請求發送多個響應
當客戶端向服務器請求數據時,服務器會順便把一些客戶端需要的資源一起推送到客戶端,免得客戶端再次創建連接發起請求到服務器請求。非常適合加載靜態資源
服務器推送可以緩存,並且在遵循同源的情況下,不同頁面之間可以共享緩存
10.http1.0與http1.1的主要區別
10.1 長連接(不會永久保持連接,而是保持一段時間,在不同服務器軟件中可以設置)
http1.0不支持長連接,默認connection:close,服務器響應請求後立馬關閉連接。而http1.1默認支持長連接,即connection:keep-alive。服務器也可以在響應頭中發送:Keep-Alive:timeout,讓瀏覽器發起關閉請求。(可以減少較多的TCP建立和關閉的操作,但可能server扛不住)
http的長連接()是爲了讓tcp活得更久一點,以便在同一個連接上傳送多個http,提高socket的效率。而tcp keep-alive是TCP的一種檢測TCP連接狀況的保鮮機制,會發送檢測包判斷TCP連接是否還存在。
keepalive是TCP保鮮定時器,當網絡兩端建立了TCP連接之後,閒置idle(雙方沒有任何數據流發送往來)了tcp_keepalive_time後,服務器內核就會嘗試向客戶端發送偵測包,來判斷TCP連接狀況(有可能客戶端崩潰、強制關閉了應用、主機不可達等等)。如果沒有收到對方的回答(ack包),則會在 tcp_keepalive_intvl後再次嘗試發送偵測包,直到收到對對方的ack,如果一直沒有收到對方的ack,一共會嘗試 tcp_keepalive_probes次,每次的間隔時間在這裏分別是15s, 30s, 45s, 60s, 75s。如果嘗試tcp_keepalive_probes,依然沒有收到對方的ack包,則會丟棄該TCP連接。TCP連接默認閒置時間是2小時,一般設置爲30分鐘足夠了。
10.2 節約帶寬
a)、http1.1支持只發送header信息(不帶任何body信息,HEAD方法),如果服務器認爲客戶端有權限訪問服務器,則返回100(繼續continue),否則返回401(未授權,需認證)。客戶端收到100纔開始把請求body發送至服務器
b)、http1.1支持傳送內容的一部分,這樣當客戶端已經有一部分的資源後,只需向服務器請求另外的部分資源。(這是支持文件斷點續傳的基礎,range字段)
10.3 host域
用於一個服務器爲多個站點提供服務,利用host判斷。
現在可以用web server(例如apache tomcat)設置虛擬站點,共享同一個ip和端口。
http1.0沒有host與,http1.1才支持這個參數