博客 / 詳情

返回

json解決跨域的實現方法及原理

  1. 先了解一下同源策略
    同源策略(英文全稱 Same origin policy)是瀏覽器提供的一個安全功能
    MDN官方給定的概念:同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互這是一個用於隔離潛在惡意文件的重要安全機制
    通俗的理解:瀏覽器規定,A 網站的 JavaScript,不允許和非同源的網站 C 之間,進行資源的交互
    例如:

         ① 無法讀取非同源網頁的 Cookie、LocalStorage 和 IndexedDB
         ② 無法接觸非同源網頁的 DOM
         ③ 無法向非同源地址發送 Ajax 請求
  2. 再瞭解一下跨域
    同源指的是兩個 URL 的協議、域名、端口一致,反之,則是跨域

     出現跨域的根本原因:**瀏覽器的同源策略**不允許非同源的 URL 之間進行資源的交互
     **注意** 瀏覽器允許發起跨域請求,但是,跨域請求回來的數據,會被瀏覽器攔截,無法被頁面獲取到!                                       

    現如今,實現跨域數據請求,最主要的兩種解決方案,分別是 JSONPCORS
    JSONP出現的早,兼容性好(兼容低版本IE)。是前端程序員為了解決跨域問題,被迫想出來的一種臨時解決方案。缺點是隻支持 GET 請求,不支持 POST 請求。
    CORS:出現的較晚,它是 W3C 標準,屬於跨域 Ajax 請求的根本解決方案。支持 GETPOST` 請求。缺點是不兼容某些低版本的瀏覽器
    其中:CORS主要是後台工作人在做 一般就是使用一箇中間鍵先截取所有的請求然後再放行

    // 跨域訪問
    app.use((req, res, next) => {
        // 1. 允許那些客户端訪問
        // * 代表允許所有的客户訪問我
        res.header('Access-Control-Allow-Origin', '*')
        // 2. 允許客户端使用那些請求方式訪問我
        res.header('Access-Control-Allow-Methods', 'get post,put,delete')
        next();
    })
  3. 瞭解jsonp
    JSONP (JSON with Padding) 是 JSON 的一種“使用模式”,可用於解決主流瀏覽器的跨域數據訪問的問題。
    JSONP的實現原理
    由於瀏覽器同源策略的限制,網頁中無法通過 Ajax 請求非同源的接口數據。但是 <script> 標籤不受瀏覽器同源策略的影響可以通過 src 屬性,請求非同源的 js 腳本。
    因此,JSONP 的實現原理,就是通過 <script> 標籤的 src 屬性,請求跨域的數據接口,而遠程服務端通過調用指定的函數並傳入參數來實現傳遞參數

    //定義一個success回調函數
    <script>
         function success(data) {
         console.log('獲取到了data數據:')
         console.log(data)
         }
     </script>
     //通過 <script> 標籤,請求接口數據:
     <script src="http://ajax:3006/api/jsonp?callback=success&name=zs&a
    ge=20"></script>

    JSONP的缺點
    由於 JSONP 是通過 <script> 標籤的 src 屬性,來實現跨域數據獲取的,所以,JSONP 只支持 GET 數據請求,不支持 POST 請求。
    注意: JSONP 和 Ajax 之間沒有任何關係,不能把 JSONP 請求數據的方式叫做 Ajax,因為 JSONP 沒有用到XMLHttpRequest 這個對象

    jQuery中的JSONP
    jQuery 提供的 $.ajax() 函數,除了可以發起真正的 Ajax 數據請求之外,還能夠發起 JSONP 數據請求,例如:

    $.ajax({
         url: 'http://ajax/api/jsonp?name=zs&age=20',
         // 如果要使用 $.ajax() 發起 JSONP 請求,必須指定 datatype 為 jsonp
         dataType: 'jsonp',
         success: function(res) {
         console.log(res)
         }
    })

    默認情況下,使用 jQuery 發起 JSONP 請求,會自動攜帶一個 callback=jQueryxxx 的參數,jQueryxxx 是隨機生成的一個回調函數名稱

    自定義參數及回調函數名稱
    在使用 jQuery 發起 JSONP 請求時,如果想要自定義 JSONP參數以及回調函數名稱,可以通過如下兩個參數來指定:

    $.ajax({
         url: 'http://ajax/api/jsonp?name=zs&age=20',
         dataType: 'jsonp',
         // 發送到服務端的參數名稱,默認值為 callback
         jsonp: 'callback',
         // 自定義的回調函數名稱,默認值為 jQueryxxx 格式
         jsonpCallback: 'abc',
         success: function(res) {
         console.log(res)
         }
    })

    jQuery中JSONP的實現過程
    jQuery 中的 JSONP,也是通過 <script> 標籤的 src 屬性實現跨域數據訪問的,只不過,jQuery 採用的是動態創建和移除標籤的方式,來發起 JSONP 數據請求。

    • 在發起 JSONP 請求的時候,動態向 頁面 中 append 一個 <script> 標籤;
    • JSONP 請求成功以後動態從頁面中移除剛才 append 進去的 <script> 標籤;
        function jsonp(obj) {
                // 1. 動態的創建一個script標籤,添加到頁面中
                var script = document.createElement('script');
                document.body.appendChild(script);
                // 2. 設置src屬性,發送script標籤的跨域請求
                // 你要執行執行哪個函數,通過callback這個屬性發過來
                script.src = obj.url + "?callback=fn&name=zs&age=23";
                // 3. 這個是接受請求後(接收的數據是一個執行函數),頁面中要提前有這個函數
                window.fn = obj.success;
                // 4. 使用完畢之後刪除script標籤
                script.onload = function () {
                    this.remove();
                }
            }
            // 具體應用
            jsonp({
                url: 'http://www.ajax.fronted.gywalker:1209/api/jsonp',
                success: function (res) {
                    console.log(res);
                }
            })
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.