最新 ajax 跨域原理及解決方式詳解

前言


前幾天,有個朋友問我跨域的問題,尋思著找篇文章給他理解。找了半天都沒有直中要害,個人認為都是理解的模棱兩可,所以花時間把自己的對ajax跨域的理解寫下來。

什么是跨域?


假設我訪問a 站點,在a站點得到一個頁面,在a 站點的這個頁面想去訪問b 站點的資源,這個是就會產生一個跨域的效果。由于瀏覽器是有安全限制的,所以a 站點無法訪問到b站點的資源。

比如我現在訪問 www.1.com 獲取到一個頁面.通過這個頁面去訪問www.2.com獲取資源。就會產生跨域。

問題展現

接口我用的是聚合數據,有接口調用次數限制,如若接口調用有問題,請自行申請接口。

1、創建一個ajaxDemo_1.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>ajax</title>
</head>

<body>
    這是一個有跨域問題的頁面
    <script src="./jquery.min.js"></script>
    <script type="text/javascript">
        $.ajax({
            type: "get",
            cache: false,
            url: 'http://apis.juhe.cn/oil/region?key=1b9411b68adda384780872fabcafc16d&city=%e5%8c%97%e4%ba%ac',
            dataType: "json",
            success: function(result) {
                console.log(JSON.stringify(result));
            },
            error: function(err) {
                console.log('err10: ');
                console.log(err);
            }
        });
    </script>
</body>

</html>
2、將ajaxDemo_1.html放到本地node.js服務器上運行
由于跨域問題產生的錯誤

ajax底層請求類型為XMLHttpRequest

如何解決?


1、jsonp(只能解決get請求跨域問題)

創建一個ajaxDemo_2.html 發起get請求
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajaxDemo_2</title>
</head>
<body>
這是一個用jsonp解決get請求跨域問題的頁面
<script src="./jquery.min.js"></script>
<script type="text/javascript">
    $.ajax({
        type: "get",
        cache: false,
        url: 'http://apis.juhe.cn/oil/region?key=1b9411b68adda384780872fabcafc16d&city=%e8%a1%a1%e9%98%b3',
        dataType: "jsonp",
        success: function(result) {
            console.log(JSON.stringify(result));
        },
        error: function(err) {
            console.log('err10: ');
            console.log(err);
        }
    });
</script>
</body>
</html>
運行后沒有跨域問題,可以正常請求到數據
ajax底層請求類型為script
ajax使用script元素發送jsonp請求

使用<script>元素進行ajax傳輸的原因:
  1、它不受同源策略的影響,因此可以使用它們從其他服務器請求數據。
  2、包含JSON編碼數據的響應體會自動解碼(即執行)。

結論:當通過<script>元素調用數據時,響應內容必須用js函數名和圓括號包裹起來,而不是發送一段json數據。而且通過<script>元素只能加載get請求而不能加載post請求

2、cors(跨域資源共享 Cross-Origin Resource Sharing)

通過cors使跨域問題在get請求和post請求都可以解決

2.1、cors原理

CORS定義一種跨域訪問的機制,可以讓AJAX實現跨域訪問。CORS 允許一個域上的網絡應用向另一個域提交跨域 AJAX 請求。實現此功能非常簡單,只需由服務器發送一個響應標頭即可

2.2CORS瀏覽器支持情況
CORS瀏覽器支持情況圖解

CORS瀏覽器支持情況描述

  喜聞樂見、普大喜奔的支持情況,尤其是在移動終端上,除了opera Mini;
  PC上的現代瀏覽器都能友好的支持,除了IE9-,不過前端工程師對這種情況早應該習慣了...

2.3 應用

假設我們頁面或者應用已在 http://www.test1.com 上了,而我們打算從 http://www.test2.com 請求提取數據。一般情況下,如果我們直接使用 AJAX 來請求將會失敗,瀏覽器也會返回“源不匹配”的錯誤,"跨域"也就以此由來。
  利用 CORS,http://www.test2.com 只需添加一個標頭,就可以允許來自 http://www.test1.com 的請求,下圖是我在服務器返回中的 header() 設置,“*”號表示允許任何域向我們的服務端提交請求:


  也可以設置指定的域名,如域名 http://www.test2.com ,那么就允許來自這個域名的請求:

  當前我設置的header為“*”,任意一個請求過來之后服務端我們都可以進行處理&響應,那么在調試工具中可以看到其頭信息設置,其中見紅框中有一項信息是“Access-Control-Allow-Origin:* ”,表示我們已經啟用CORS。

cors示例

示例代碼

https://github.com/yangxiaopingios/AjaxDemo

參考資料

http://www.ruanyifeng.com/blog/2016/04/cors.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容