前端基礎整理 | 網絡相關(二)

文章首發地址:http://www.brandhuang.com/article/1585139147636html

跨域

在先後端分離的開發模式中,常常發生跨域的問題,前端發送了請求,服務器也作出了響應,可是前端卻拿不到這個響應前端

爲何服務器作出了正確的響應,前端卻拿不到這個響應呢?chrome

由於瀏覽器都遵循一個同源策略(協議、主機和端口都相同,則同源)。對非同源站點,瀏覽器會做出一些限制:segmentfault

  • 不能讀取和修改對方的 DOM
  • 不讀訪問對方的 Cookie、IndexDB 和 LocalStorage
  • 限制 XMLHttpRequest 請求。

當瀏覽器向服務器發起 Ajax 請求時,若是當前的 URL 和目標的 URL不一樣源,則爲 跨域請求後端

跨域請求的響應會被客戶端攔截(注意:響應其實已經被客戶端獲取到了,只是被攔截了api

處理跨域 | CORS

CORS 是 W3C 的一個標準,全稱 跨域資源共享。支持非 ie 以及 ie10 以上。 須要服務器附加特定的響應頭

瀏覽器根據請求方法和請求頭的特定字段,將請求分爲了簡單請求非簡單請求。針對這兩類不一樣的請求進行不一樣的處理跨域

簡單請求

簡單請求知足如下條件:瀏覽器

  • 請求方法爲 GET、POST 或者 HEAD
  • 請求頭的取值範圍: Accept、Accept-Language、Content-Language、Content-Type(只限於三個值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目標地址,同時加上兩個關鍵字段:

  • Access-Control-Request-Method, 列出 CORS 請求用到哪一個HTTP方法
  • Access-Control-Request-Headers,指定 CORS 請求將要加上什麼請求頭

預檢請求響應以下:

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請求也不會發出去了。

處理跨域 | JSONP

原理:動態建立script標籤,它能夠經過 src 填上目標地址從而發出 GET 請求,實現跨域請求並拿到響應.

JSONP 與 CORS 比較

CORS相比,JSONP 最大的優點在於兼容性好,IE 低版本不能使用 CORS 但可使用 JSONP,缺點也很明顯,請求方法單一,只支持 GET 請求。

處理跨域 | Nginx

服務器進行以下配置:

server {
  listen  80;
  server_name  client.com;
  location /api {
    proxy_pass server.com;
  }
}

處理跨域 | PostMessage

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:短輪詢、長輪詢、長鏈接
  • 非 HTTP:Websocket

短輪詢(Polling)

基本實現思路:瀏覽器每隔一段時間定時向服務器發送 HTTP 請求,服務器收到請求後當即進行響應(無論內容是否發生變化)。響應完成後 TCP 鏈接關閉。

長輪詢(Comet)

基本實現思路:當服務器收到客戶端發來的請求後,不會直接進行響應,而是先將這個請求掛起,而後判斷服務器端數據是否有更新。若是有更新,則進行響應,若是一直沒有數據,則到達必定的時間限制(服務器端設置)後關閉鏈接。

長輪詢和短輪詢比起來,減小了不少沒必要要的http請求次數。可是長輪詢的鏈接一直掛起也會致使資源的浪費。

長鏈接(SSE)

查看 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

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);
});

CDN

全稱 content delivery network,內容分發網絡。是一組分佈在多個不一樣的地理位置的服務器。根據用戶的實際位置,從離用戶最近的 CDN 服務器爲用戶提供內容,提升訪問速度,提高用戶體驗。

主要用來解決網絡擁堵,提升訪問速度,解決因爲網絡帶寬小,用戶訪問量大,網點分佈不均等緣由致使的訪問速度慢的問題。

CDN的大體原理:

  1. 用戶在瀏覽器輸入要訪問的域名;
  2. 對域名進行解析,因爲CDN對域名解析過程進行了調整,因此解析函數庫通常獲得的是該域名對應的CNAME記錄,爲了獲得實際的IP地址,瀏覽器須要再次對得到的CNAME域名進行解析以獲得實際的IP地址;在此過程當中,使用的全局負載均衡DNS解析。如根據地理位置信息解析對應的IP地址,使得用戶能就近訪問;
  3. 這次解析獲得CDN緩存服務器的IP地址,瀏覽器在獲得實際的ip地址以後,向緩存服務器發出訪問請求;
  4. 緩存服務器根據瀏覽器提供的要訪問的域名,經過Cache內部專用DNS解析獲得此域名的實際IP地址,再由緩存服務器向此實際IP地址提交訪問請求;
  5. 緩存服務器從實際IP地址獲得內容之後,一方面在本地進行保存,以備之後使用,二方面把獲取的數據放回給客戶端,完成數據服務過程;
  6. 客戶端獲得由緩存服務器返回的數據之後顯示出來並完成整個瀏覽的數據請求過程。

本文先整理這麼多吧,反正一次也消化不完。

若是喜歡本文但願能點個贊~

固然能夠關注我來獲取後續文章

也能夠關注我我的博客

還也能夠關注我公衆號「九零後重慶崽兒」。

brand.jpg

相關文章
相關標籤/搜索