文章首發地址:http://www.brandhuang.com/article/1585139147636html
在先後端分離的開發模式中,常常發生跨域的問題,前端發送了請求,服務器也作出了響應,可是前端卻拿不到這個響應
。前端
爲何服務器作出了正確的響應,前端卻拿不到這個響應呢?chrome
由於瀏覽器都遵循一個同源策略(協議、主機和端口都相同,則同源)
。對非同源站點,瀏覽器會做出一些限制:segmentfault
當瀏覽器向服務器發起 Ajax 請求時,若是當前的 URL 和目標的 URL不一樣源,則爲 跨域請求
。後端
跨域請求的響應會被客戶端攔截(注意:響應其實已經被客戶端獲取到了,只是被攔截了
)api
CORS 是 W3C 的一個標準,全稱跨域資源共享
。支持非 ie 以及 ie10 以上。須要服務器附加特定的響應頭
。
瀏覽器根據請求方法和請求頭的特定字段,將請求分爲了簡單請求
和非簡單請求
。針對這兩類不一樣的請求進行不一樣的處理跨域
簡單請求知足如下條件:瀏覽器
application/x-www-form-urlencoded、multipart/form-data、text/plain
)請求發出去前,瀏覽器在請求頭中添加 Origin
字段,服務器在響應中添加 Access-Control-Allow-Origin
字段,若是這個字段不在 Origin
字段的範圍中,則瀏覽器攔截響應。所以,Access-Control-Allow-Origin
字段是服務器用來決定瀏覽器是否攔截這個響應,這是必需的字段。緩存
Access-Control-Allow-Credentials
是一個布爾值,表示是否容許發送 Cookie。瀏覽器對這個字段默認值設爲 false
,若要瀏覽器請求攜帶cookie,須要添加這個響應頭並設爲true, 而且在前端也須要設置withCredentials屬性爲 true,服務器
let xhr = new XMLHttpRequest(); xhr.withCredentials = true;
除了簡單請求以外的請求 (PUT DELETE PATCH等)
發起非簡單請求時,會先發起預檢請求(OPTIONS)
,同時會加上Origin
源地址和Host
目標地址,同時加上兩個關鍵字段:
預檢請求響應以下:
HTTP/1.1 200 OK Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header Access-Control-Allow-Credentials: true Access-Control-Max-Age: 1728000 Content-Type: text/html; charset=utf-8 Content-Encoding: gzip Content-Length: 0
在預檢請求的響應返回後,若是請求不知足響應頭的條件,則觸發XMLHttpRequest的onerror
方法,固然後面真正的CORS請求也不會發出去了。
原理:動態建立script
標籤,它能夠經過 src 填上目標地址從而發出 GET 請求,實現跨域請求並拿到響應.
和CORS
相比,JSONP
最大的優點在於兼容性好,IE 低版本不能使用 CORS
但可使用 JSONP
,缺點也很明顯,請求方法單一,只支持 GET 請求。
服務器進行以下配置:
server { listen 80; server_name client.com; location /api { proxy_pass server.com; } }
MDN文檔: window.postMessage
otherWindow.postMessage(message, targetOrigin, [transfer]); window.addEventListener("message", receiveMessage, false); function receiveMessage(event) { // For Chrome, the origin property is in the event.originalEvent // object. // 這裏不許確,chrome沒有這個屬性 // var origin = event.origin || event.originalEvent.origin; var origin = event.origin if (origin !== "http://example.org:8080") return; // ... }
更詳細的解釋,能夠參看神三元大佬的文章:http://www.javashuo.com/article/p-unqnwopd-ep.html
即時通信,一種基於互聯網的即時交流消息的業務。。
實現即時通信主要有四種方式:短輪詢
、長輪詢(comet)
、長鏈接(SSE)
、WebSocket
。
上述四種可分爲兩類:
基本實現思路:瀏覽器每隔一段時間定時向服務器發送 HTTP 請求,服務器收到請求後當即進行響應(無論內容是否發生變化)。響應完成後 TCP 鏈接關閉。
基本實現思路:當服務器收到客戶端發來的請求後,不會直接進行響應,而是先將這個請求掛起,而後判斷服務器端數據是否有更新。若是有更新,則進行響應,若是一直沒有數據,則到達必定的時間限制(服務器端設置)後關閉鏈接。
長輪詢和短輪詢比起來,減小了不少沒必要要的http請求次數
。可是長輪詢的鏈接一直掛起
也會致使資源的浪費。
查看 MDN文檔
HTML5新增的功能,由客戶端發起
與服務器之間建立TCP鏈接,並維持這個鏈接,直到客戶端或服務器中的任何一方斷開。鏈接建立後,瀏覽器會週期性地發送消息至服務器詢問
。HTTP響應內容有一種特殊的content-type —— text/event-stream
,該響應頭標識了響應內容爲事件流
,客戶端不會關閉鏈接
,而是等待服務端不斷得發送響應結果。
使用:
var source = new EventSource('/XXX'); // 默認的事件 source.addEventListener('message', function (e) { console.log(e.data); }, false); // 用戶自定義的事件名 source.addEventListener('my_msg', function (e) { process(e.data); }, false); // 監聽鏈接打開 source.addEventListener('open', function (e) { console.log('open sse'); }, false); // 監聽錯誤 source.addEventListener('error', function (e) { console.log('error'); });
WebSocket是Html5定義的一個新協議,與傳統的 HTTP 協議不一樣,可實現服務端和客戶端雙向同時通訊(全雙工通訊)
。
首先經過 HTTP 來讓客戶端和服務端創建鏈接,鏈接創建後就再也不使用 HTTP 協議,便可進行數據傳遞。
const socket = new WebSocket('ws://localhost:8080'); // Connection opened socket.addEventListener('open', function (event) { socket.send('Hello Server!'); }); // Listen for messages socket.addEventListener('message', function (event) { console.log('Message from server ', event.data); });
全稱 content delivery network,內容分發網絡。是一組分佈在多個不一樣的地理位置的服務器。根據用戶的實際位置,從離用戶最近的 CDN 服務器爲用戶提供內容,提升訪問速度,提高用戶體驗。
主要用來解決網絡擁堵,提升訪問速度,解決因爲網絡帶寬小,用戶訪問量大,網點分佈不均等緣由致使的訪問速度慢的問題。
CDN的大體原理:
獲得的是該域名對應的CNAME記
錄,爲了獲得實際的IP地址,瀏覽器須要再次對得到的CNAME域名進行解析
以獲得實際的IP地址;在此過程當中,使用的全局負載均衡DNS解析。如根據地理位置信息解析對應的IP地址,使得用戶能就近訪問;獲得CDN緩存服務器的IP地址
,瀏覽器在獲得實際的ip地址以後,向緩存服務器發出訪問請求;獲得此域名的實際IP地址
,再由緩存服務器向此實際IP地址提交訪問請求;本文先整理這麼多吧,反正一次也消化不完。
若是喜歡本文但願能點個贊~
固然能夠關注我來獲取後續文章
也能夠關注我我的博客
還也能夠關注我公衆號「九零後重慶崽兒」。