1. 程式人生 > 程式設計 >深入淺析同源與跨域,jsonp(函式封裝),CORS原理

深入淺析同源與跨域,jsonp(函式封裝),CORS原理

目錄
  • 同源政策
    • Ajax請求限制:
      • Ajax 只能向自己的伺服器傳送請求
    • 同源:
      • 同源政策的目的:
        • 不受同源策略限制:
        • 跨域問題
          • 跨域的原因:
            • 解決跨域問題:
              • 使用 ONP 解決
              • 解決方法:
          • JSONP
            • JSONP的優缺點:
              • JSONP程式碼優化:
                • JSONP函式封裝:
                • CORS
                  • 使用CORS解決
                    • Express框架中跨域的實現:

                    同源政策

                    Ajax請求限制:

                    Ajax 只能向自己的伺服器傳送請求

                    同源策略是瀏覽器的一個安全功能,不同源的客戶端在沒有明確授權的情況下,不能讀寫對方資源。

                    比如現在有一個A、有一個B網站,A網站中的 HTML 檔案只能向A網站伺服器中傳送 Ajax 請求,

                    B網站中的 HTML 檔案只向 B 網站中傳送 Ajax 請求,但是 A 網站是不能向 B 網站傳送 Ajax請求的,

                    同理,B 網站也不能向 A 網站傳送 Ajax請求。

                    同源:

                    如果兩個頁面擁有相同的協議、域名和埠,那麼這兩個頁面就屬於同一個源,其中只要有一個不相同,就是不同源。

                    http://www.example.com/dir/page.html

                    http://www.example.com/dir2/other.html:同源http://example.com/dir/other.html:不同源(域名不同)

                    http://v2.www.example.com/dir/other.html:不同源(域名不同)

                    http://www.example.com:81/dir/other.html:不同源(埠不同)

                    https://www.example.com/dir/page.html:不同源(協議不同)

                    同源政策的目的:

                    • 同源政策是為了保證使用者資訊的安全,防止惡意的網站竊取資料。最初的同源政策是指 A 網站在客戶端設定的 Cookie,B網站是不能訪問的。
                    • 隨著網際網路的發展,同源政策也越來越嚴格,在不同源的情況下,其中有一項規定就是無法向非同源地址傳送Ajax 請求,如果請求,瀏覽器就會報錯。

                    不受同源策略限制:

                    頁面中的連結,重定向以及表單提交是不會受到同源策略限制的跨域資源的引入是可以的。但是js不能讀寫載入的內容。如嵌入到頁面中的<script src="..."></script><img><link><iframe>

                    跨域問題

                    跨域:只要協議、域名、埠號有一個不同就是跨域

                    跨域的原因:

                    跨域問題 來源於 的同源策略,即只有 協議+主機名+埠號(如存在)相同,則允許相互訪問。

                    為了防止某域名下的介面被其他域名下的非法呼叫,是瀏覽器對Script施加的安全限制。

                    也就是說JavaScript只能訪問和操作自己域下的資源,不能訪問和操作其他域下的資源。

                    跨域問題是針對 JS 和 Ajax 的, html 本身沒有跨域問題,

                    比如a標籤、script標籤、TcZYUK甚至form標籤(可以直接跨域傳送資料並接收資料) 等

                    解決跨域問題:

                    JSONP:利用script標籤可跨域的特點,在跨域指令碼中可以直接回調當前指令碼的函式。

                    CORS:伺服器設定HTTP響應頭中Access-Control-Allow-Origin值,解除跨域限制。 注意:這兩個跨域方案都存在一個致命的缺陷,嚴重依賴後端的協助。

                    反向代理(Reverse Proxy):前端獨立就能解決的跨域方案:

                    指以 代理伺服器 來接受internet上的連線請求,

                    然後將請求轉發給內部網路上的伺服器,

                    並將從伺服器上得到的結果返回給internet上請求連線的客戶端,

                    此時代理伺服器對外就表現為一個反向代理伺服器。

                    JSONP

                    使用 JSONP 解決

                    jsonp 是 JSON with padding(填充式 JSON 或引數式 JSON)的簡寫,它 不屬於 Ajax 請求,但它可以 模擬 Ajax 請求

                    JSONP 由兩部分組成:回撥函式和資料

                    • 回撥函式是當響應到來時應該在頁面中呼叫的函式。回撥函式的名字一般是在請求中指定的。
                    • 資料就是傳入回撥函式中的 JSON 資料。

                    解決方法:

                    簡單理解:在伺服器端將json資料作為函式引數,填充到函式當中,在客戶端中呼叫函式從而對資料進行處理

                    在這裡插入圖片描述

                    JSONP實現跨域請求的原理簡單的說,就是動態建立<script>標籤,然後利用<script>的 src 不受同源策略約束來跨域獲取資料。

                    JSONP的優缺點:

                    優點:

                    不像XMLHttpRequest物件實現的Ajax請求那樣受到同源策略的限制相容性更好,在更加古老的瀏覽器中都可以執行,

                    不需要XMLHttpRequest或ActiveX的支援並且在請求完畢後可以通過呼叫callback的方式回傳結果

                    缺點:

                    只支援GET請求而不支援POST等其它型別的HTTP請求只支援跨域HTTP請求這種情況,

                    不能解決不同域的兩個頁面之間如何進行JavaScript呼叫的問題

                    JSONP程式碼優化:

                    客戶端需要將函式名稱傳遞到伺服器端

                    將 script 請求的傳送變成動態請求

                    封裝 jsonp 函式,方便請求傳送

                    伺服器端程式碼優化之res.jsonp 方法

                    JSONP函式封裝:

                    function jsonp (options) {
                        // 動態建立script標籤
                        var scripthttp://www.cppcns.com = document.createElement('script');
                        // 拼接字串的變數
                        var params = '';
                        for (var attr in options.data) {
                            params += '&' + attr + '=' + options.data[attr];
                        }
                        // myJsonp0124741
                        var fnName = 'myJsonp' + Math.random().toString().replace('.','');
                        // 將它變成全域性函式
                        window[fnName] = options.success;
                        // 為script標籤新增src屬性
                        script.src = options.url + '?callback=' + fnName + params;
                        // 將script標籤追加到頁面中
                        document.body.appendChild(script);
                        // 為script標籤新增onload事件
                        script.onload = function () {
                            document.body.removeChild(script);
                        }
                    }
                    

                    使用:

                    // 獲取按鈕
                    var btn1 = document.getElementById('btn1');
                    var btn2 = document.getElementById('btn2');
                    // 為按鈕新增點選事件
                    btn1.onclick = function () {
                        jsonp({
                            // 請求地址
                            url: 'http://localhost:3001/better',data: {
                                name: 'lisi',age: 30
                            },success: function (data) {
                                console.log(123)
                                console.log(data)
                            }
                        })
                    }
                    btn2.onclick = function () {
                        jsonp({
                            // 請求地址
                            url: 'http://localhost:3001/better',success: function (data) {
                      www.cppcns.com          console.log(456789)
                                console.log(data)
                            }
                        })
                    }
                    

                    CORS

                    使用CORS解決

                    CORS:全稱為 Cross-origin resource sharing,即跨域資源共享,它允許瀏覽器向跨域伺服器傳送 Ajax 請求,克服了 Ajax 只能同源使用的限制。

                    在這裡插入圖片描述

                    //設定伺服器的響應頭資訊,實現跨域
                    res.setHeader("Access-Control-Allow-Origin","*");  /* 星號表示所有的域都可以接受, */
                    

                    Express框架中跨域的實現:

                    安裝跨域模組:語法: npm install cors

                    在app.js檔案中引入cors模組:var cors = require('cors')

                    使用跨域模組(在app.js檔案中) :app.use(cors())

                    以上就是深入淺析同源與跨域,jsonp(函式封裝),CORS原理的詳細內容,更多關於同源與跨域,CORS的資料請關注我們其它相關文章!