關於前端如何解決跨域問題


跨域

什么是跨域

  瀏覽器為保證安全,增加的同源限制,其實請求是發出了,服務器也相應了,但是被瀏覽器劫持了。所謂同源是指,域名,協議,端口均相同,瀏覽器才會覺得符合要求。

  一旦有一個不同源,瀏覽器便會觸發安全機制。

跨域解決辦法有哪些?

應該有很多,我就介紹JSONP, CORS, window.postMessage這三種理解的比較好的

  • JSONP

    原理: <script>標簽不受跨域限制,ps:所有src屬性都不受同源限制,比如<img>

JSONP缺點: 只支持GET請求,不支持其他類型請求;優點:兼容性很好好,可以在古老的瀏覽器中運行。

  • CORS

    CORS是一個W3C標准,全稱是"跨域資源共享"(Cross-origin resource sharing)。它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求。

把請求分為了兩種:簡單請求和復雜請求。

如何分辨簡單請求和復雜請求呢?只要不符合下面條件,就是復雜請求。

  • 請求方法是以下三種方法之一:

HEAD

GET

POST

  • HTTP的頭信息不超出以下幾種字段:

Accept

Accept-Language

Content-Language

Last-Event-ID

Content-Type:只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain


知識點:

  • 面對復雜請求,瀏覽器會在第一次先發送一個預檢請求,預檢請求使用的是OPTIONS方法,攜帶Origin, Access-Control-Request-Method, Access-Control-Request-Headers

  • 服務器拒絕的話,返回也是正常http響應,只是沒有Access-Control-Allow-Origin字段; 服務器同意的話,返回的響應里除了Access-Control-Allow-Origin,還會有
Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials,//它的值是一個布爾值,表示是否允許發送Cookie。默認false,不發送 Access-Control-Max-Age // 該字段可選,用來指定本次預檢請求的有效期,單位為秒, 在此期間,不用發出另一條預檢請求。
  • 一旦服務器通過了"預檢"請求,以后每次瀏覽器正常的CORS請求,就都跟簡單請求一樣,會有一個Origin頭信息字段。服務器的回應,也都會有一個Access-Control-Allow-Origin頭信息字段。

  • HTML5 window.postMessage API

    window.postMessage是一個安全的,基於事件的消息API

  1. 發送消息

需要發送的窗口winA,調用postMessage方法,即可發送消息,其中winA還可以是文檔窗口中的iframe:

  var iframe = document.getElementById('my-iframe'); var win = iframe.documentWindow;

postMessage語法:otherWindow.postMessage(message, targetOrigin, [transfer]);
舉栗子:win.postMessage('Hello', 'ttp://jhssdemo.duapp.com/');

  1. 接收消息

要想接收到之前源窗口通過postMessage發出的消息,只需要在目標窗口注冊message事件並綁定事件監聽函數,就可以在函數參數中獲取消息。

注意:postMessage只能發送字符串信息。


    window.onload = function() { var text = document.getElementById('txt'); function receiveMsg(e) { // e 有三個屬性:data, origin, source console.log("Got a message!"); console.log("\nMessage: " + e.data); console.log("\nOrigin: " + e.origin); // console.log("Source: " + e.source); text.innerHTML = "Got a message!<br>" + "Message: " + e.data + "<br>Origin: " + e.origin; } if (window.addEventListener) { //為窗口注冊message事件,並綁定監聽函數 window.addEventListener('message', receiveMsg, false); }else { window.attachEvent('message', receiveMsg); } };


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM