79. http 響應碼 301 和 302 表明的是什麼?有什麼區別? 80. forward 和 redirect 的區別? 81. get 和 post 請求有哪些區別? 82. tcp 爲何要三次握手,兩次不行嗎?爲何? 83. 說一下 tcp 粘包是怎麼產生的? 84. OSI 的七層模型都有哪些? 85. 簡述 tcp 和 udp的區別? 86. 如何實現跨域? 87. 說一下 JSONP 實現原理?
網絡html
79. http 響應碼 301 和 302 表明的是什麼?有什麼區別?前端
答:301,302 都是HTTP狀態的編碼,都表明着某個URL發生了轉移。算法
區別:json
80. forward 和 redirect 的區別?跨域
都是servlet種的兩種主要的跳轉方式。
forward 又叫轉發(經典的MVC模式)
redirect 叫作重定向(它通常用於避免用戶的非正常訪問。例如:用戶在沒有登陸的狀況下訪問後臺資源,Servlet能夠將該HTTP請求重定向到登陸頁面)瀏覽器
二者的區別總結:安全
1)forword是服務器內部的重定向,服務器直接訪問目標地址的 url網址,把裏面的東西讀取出來,可是客戶端並不知道,所以用forward的話,客戶端瀏覽器的網址是不會發生變化的。服務器
2)redirect是服務器根據邏輯,發送一個狀態碼,告訴瀏覽器從新去請求那個地址,因此地址欄顯示的是新的地址。網絡
1)因爲在整個定向的過程當中用的是同一個request,所以forward會將request的信息帶到被重定向的jsp或者servlet中使用。即request能夠共享數據前端工程師
2)redirect不能共享
1)forword效率高,而redirect效率低
forword轉發是服務器上的行爲,而redirect重定向是客戶端的行爲
forword只有一次請求;而redirect有兩次請求,
直接轉發方式(Forward),客戶端和瀏覽器只發出一次請求,Servlet、HTML、JSP或其它信息資源,由第二個信息資源響應該請求,在請求對象request中,保存的對象對於每一個信息資源是共享的。
間接轉發方式(Redirect),實際是兩次HTTP請求,服務器端在響應第一次請求的時候,讓瀏覽器再向另一個URL發出請求,從而達到轉發的目的。
81. get 和 post 請求有哪些區別?
最直觀的區別就是GET把參數包含在URL中,POST經過request body傳遞參數。
但本質上GET和POST請求是同樣同樣的,詳見 https://www.cnblogs.com/logsh...
GET和POST是什麼?HTTP協議中的兩種發送請求的方法。HTTP的底層是TCP/IP。因此GET和POST的底層也是TCP/IP,也就是說,GET/POST都是TCP連接。GET和POST能作的事情是同樣同樣的。你要給GET加上request body,給POST帶上url參數,技術上是徹底行的通的。可是因爲HTTP的規定和瀏覽器/服務器的限制,致使他們在應用過程當中體現出一些不一樣。
GET和POST還有一個重大區別:
雖然看起來GET比POST更有效,但據研究,在網絡環境好的狀況下,發一次包的時間和發兩次包的時間差異基本能夠無視。而在網絡環境差的狀況下,兩次包的TCP在驗證數據包完整性上,有很是大的優勢,並且並非全部瀏覽器都會在POST中發送兩次包,Firefox就只發送一次
82. tcp 爲何要三次握手,兩次不行嗎?爲何?
爲了實現可靠數據傳輸, TCP 協議的通訊雙方, 都必須維護一個序列號, 以標識發送出去的數據包中, 哪些是已經被對方收到的。 三次握手的過程便是通訊雙方相互告知序列號起始值, 並確認對方已經收到了序列號起始值的必經步驟。
若是隻是兩次握手, 至多隻有鏈接發起方的起始序列號能被確認, 另外一方選擇的序列號則得不到確認。
83. 說一下 tcp 粘包是怎麼產生的?
①. 發送方產生粘包
採用TCP協議傳輸數據的客戶端與服務器常常是保持一個長鏈接的狀態(一次鏈接發一次數據不存在粘包),雙方在鏈接不斷開的狀況下,能夠一直傳輸數據;但當發送的數據包過於的小時,那麼TCP協議默認的會啓用Nagle算法,將這些較小的數據包進行合併發送(緩衝區數據發送是一個堆壓的過程);這個合併過程就是在發送緩衝區中進行的,也就是說數據發送出來它已是粘包的狀態了。
②. 接收方產生粘包
接收方採用TCP協議接收數據時的過程是這樣的:數據到底接收方,從網絡模型的下方傳遞至傳輸層,傳輸層的TCP協議處理是將其放置接收緩衝區,而後由應用層來主動獲取(C語言用recv、read等函數);這時會出現一個問題,就是咱們在程序中調用的讀取數據函數不能及時的把緩衝區中的數據拿出來,而下一個數據又到來並有一部分放入的緩衝區末尾,等咱們讀取數據時就是一個粘包。(放數據的速度 > 應用層拿數據速度)
84. OSI 的七層模型都有哪些?
85. 簡述 tcp 和 udp的區別?
網絡協議是每一個前端工程師都必需要掌握的知識,TCP/IP 中有兩個具備表明性的傳輸層協議,分別是 TCP 和 UDP
86. 如何實現跨域?
方式一:圖片ping或script標籤跨域
圖片ping經常使用於跟蹤用戶點擊頁面或動態廣告曝光次數。
script標籤能夠獲得從其餘來源數據,這也是JSONP依賴的根據。
方式二:JSONP跨域
JSONP(JSON with Padding)是數據格式JSON的一種「使用模式」,可讓網頁從別的網域要數據。根據 XmlHttpRequest 對象受到同源策略的影響,而利用 <script>元素的這個開放策略,網頁能夠獲得從其餘來源動態產生的JSON數據,而這種使用模式就是所謂的 JSONP。用JSONP抓到的數據並非JSON,而是任意的JavaScript,用 JavaScript解釋器運行而不是用JSON解析器解析。全部,經過Chrome查看全部JSONP發送的Get請求都是js類型,而非XHR。
缺點:
方式三:CORS
Cross-Origin Resource Sharing(CORS)跨域資源共享是一份瀏覽器技術的規範,提供了 Web 服務從不一樣域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,確保安全的跨域數據傳輸。現代瀏覽器使用CORS在API容器如XMLHttpRequest來減小HTTP請求的風險來源。與 JSONP 不一樣,CORS 除了 GET 要求方法之外也支持其餘的 HTTP 要求。服務器通常須要增長以下響應頭的一種或幾種:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-PINGOTHER, Content-Type Access-Control-Max-Age: 86400
跨域請求默認不會攜帶Cookie信息,若是須要攜帶,請配置下述參數:
"Access-Control-Allow-Credentials": true // Ajax設置 "withCredentials": true
方式四:window.name+iframe
window.name經過在iframe(通常動態建立i)中加載跨域HTML文件來起做用。而後,HTML文件將傳遞給請求者的字符串內容賦值給window.name。而後,請求者能夠檢索window.name值做爲響應。
每一個iframe都有包裹它的window,而這個window是top window的子窗口。contentWindow屬性返回<iframe>元素的Window對象。你可使用這個Window對象來訪問iframe的文檔及其內部DOM。
<!-- 下述用端口 10000表示:domainA 10001表示:domainB --> <!-- localhost:10000 --> <script> var iframe = document.createElement('iframe'); iframe.style.display = 'none'; // 隱藏 var state = 0; // 防止頁面無限刷新 iframe.onload = function() { if(state === 1) { console.log(JSON.parse(iframe.contentWindow.name)); // 清除建立的iframe iframe.contentWindow.document.write(''); iframe.contentWindow.close(); document.body.removeChild(iframe); } else if(state === 0) { state = 1; // 加載完成,指向當前域,防止錯誤(proxy.html爲空白頁面) // Blocked a frame with origin "http://localhost:10000" from accessing a cross-origin frame. iframe.contentWindow.location = 'http://localhost:10000/proxy.html'; } }; iframe.src = 'http://localhost:10001'; document.body.appendChild(iframe); </script> <!-- localhost:10001 --> <!DOCTYPE html> ... <script> window.name = JSON.stringify({a: 1, b: 2}); </script> </html>
方式五:window.postMessage()
HTML5新特性,能夠用來向其餘全部的 window 對象發送消息。須要注意的是咱們必需要保證全部的腳本執行完才發送 MessageEvent,若是在函數執行的過程當中調用了它,就會讓後面的函數超時沒法執行。
下述代碼實現了跨域存儲localStorage
<!-- 下述用端口 10000表示:domainA 10001表示:domainB --> <!-- localhost:10000 --> <iframe src="http://localhost:10001/msg.html" name="myPostMessage" style="display:none;"> </iframe> <script> function main() { LSsetItem('test', 'Test: ' + new Date()); LSgetItem('test', function(value) { console.log('value: ' + value); }); LSremoveItem('test'); } var callbacks = {}; window.addEventListener('message', function(event) { if (event.source === frames['myPostMessage']) { console.log(event) var data = /^#localStorage#(d+)(null)?#([Ss]*)/.exec(event.data); if (data) { if (callbacks[data[1]]) { callbacks[data[1]](data[2] === 'null' ? null : data[3]); } delete callbacks[data[1]]; } } }, false); var domain = '*'; // 增長 function LSsetItem(key, value) { var obj = { setItem: key, value: value }; frames['myPostMessage'].postMessage(JSON.stringify(obj), domain); } // 獲取 function LSgetItem(key, callback) { var identifier = new Date().getTime(); var obj = { identifier: identifier, getItem: key }; callbacks[identifier] = callback; frames['myPostMessage'].postMessage(JSON.stringify(obj), domain); } // 刪除 function LSremoveItem(key) { var obj = { removeItem: key }; frames['myPostMessage'].postMessage(JSON.stringify(obj), domain); } </script> <!-- localhost:10001 --> <script> window.addEventListener('message', function(event) { console.log('Receiver debugging', event); if (event.origin == 'http://localhost:10000') { var data = JSON.parse(event.data); if ('setItem' in data) { localStorage.setItem(data.setItem, data.value); } else if ('getItem' in data) { var gotItem = localStorage.getItem(data.getItem); event.source.postMessage( '#localStorage#' + data.identifier + (gotItem === null ? 'null#' : '#' + gotItem), event.origin ); } else if ('removeItem' in data) { localStorage.removeItem(data.removeItem); } } }, false); </script>
注意Safari一下,會報錯:
Blocked a frame with origin 「 http://localhost:10001」 from accessing a frame with origin 「 http://localhost:10000「. Protocols, domains, and ports must match.
避免該錯誤,能夠在Safari瀏覽器中勾選開發菜單==>停用跨域限制。或者只能使用服務器端轉存的方式實現,由於Safari瀏覽器默認只支持CORS跨域請求。
方式六:修改document.domain跨子域
前提條件:這兩個域名必須屬於同一個基礎域名!並且所用的協議,端口都要一致,不然沒法利用document.domain進行跨域,因此只能跨子域
在根域範圍內,容許把domain屬性的值設置爲它的上一級域。例如,在」aaa.xxx.com」域內,能夠把domain設置爲 「xxx.com」 但不能設置爲 「xxx.org」 或者」com」。
如今存在兩個域名aaa.xxx.com和bbb.xxx.com。在aaa下嵌入bbb的頁面,因爲其document.name不一致,沒法在aaa下操做bbb的js。能夠在aaa和bbb下經過js將document.name = 'xxx.com';設置一致,來達到互相訪問的做用。
方式七:WebSocket
WebSocket protocol 是HTML5一種新的協議。它實現了瀏覽器與服務器全雙工通訊,同時容許跨域通信,是server push技術的一種很棒的實現。相關文章,請查看:WebSocket、WebSocket-SockJS
須要注意:WebSocket對象不支持DOM 2級事件偵聽器,必須使用DOM 0級語法分別定義各個事件。
方式八:代理
同源策略是針對瀏覽器端進行的限制,能夠經過服務器端來解決該問題
DomainA客戶端(瀏覽器) ==> DomainA服務器 ==> DomainB服務器 ==> DomainA客戶端(瀏覽器)
來源:blog.csdn.net/ligang2585116/article/details/73072868
87.說一下 JSONP 實現原理?
jsonp 即 json+padding,動態建立script標籤,利用script標籤的src屬性能夠獲取任何域下的js腳本,經過這個特性(也能夠說漏洞),服務器端不在返貨json格式,而是返回一段調用某個函數的js代碼,在src中進行了調用,這樣實現了跨域。