[Ajax](三)跨域請求解決(jsonp、cors)

概念

同源策略是瀏覽器的一種安全策略,所謂同源是指域名、協議(http、https)、端口徹底相同,只有同源的地址才能夠相互經過AJAX的方式請求。不一樣源地址之間,默認不能相互發送AJAX請求html

同源或者不一樣源說的是兩個地址之間的關係,不一樣源地址之間請求咱們稱之爲跨域請求。node

http://www.baidu.com:80和ftp://www.baidu.com:80                            不一樣域,協議不同ajax

http://www.baidu.com:80和http://www.xiaomi.com:80                        不一樣域,主機名不同express

http://www.baidu.com:80和ftp://www.baidu.com:8080                        不一樣域,端口號不同json

http://www.baidu.com:80/a.html和ftp://www.baidu.com:80/b.js           同域跨域

 

跨域請求的來龍去脈

爲何瀏覽器要限制跨域請求,其中最主要的緣由就是安全性問題,好比CSRF攻擊。可是,既然不安全,爲何咱們又要跨域請求呢?爲了服務器便於管理和減輕服務器壓力,公司會把不一樣的資源放在不一樣的服務器上,這樣就存在不少子域,這時好比A子域的html資源要去訪問B子域的圖片資源就會出現跨域請求了。(能夠注意下京東網站就是個很好的例子)瀏覽器

 

方法1、JSONP

ajax請求不一樣域會出現跨域請求,無訪問權限緩存

//報錯CORS header ‘Access-Control-Allow-Origin’ missing
$.get("http://locally.uieee.com/categories", {},
    function (data, textStatus, jqXHR) {
        console.log(data)
    },
);

但平時在HTML頁面寫的<script>、<link>這些標籤的src屬性是不受跨域請求限制的。安全

var script = document.createElement('script')
script.src = 'http://locally.uieee.com/categories'//返回的是json
document.body.appendChild(script)

JSONP的策略就是服務器端能夠動態生成JSON文件,把客戶端須要的數據放到這個文件中,讓客戶端經過<script>標籤的src屬性來請求這個文件,這樣,一種解決方案就出來了。服務器

客戶端 

 在任意位置寫一個html頁面

服務端    

在nodejs的express框架裏的public寫一個js文件,靜態資源都放在這裏。

雙擊打開.html文件可看結果

注意

JSONP方式沒法發送POST請求,只能經過URL後面帶參數實現,並且想要肯定JSONP的請求是否失敗並不容易,大多數實現都是結合超時時間來進行判斷的。

 

方法2、CORS跨資源共享

它容許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。

這種方案無需客戶端作出任何變化(客戶端不用改代碼),只是在被請求的服務端響應的時候添加一個響應頭Access-Control-Allow-Origin,表示這個資源是否容許指定域請求。

服務器端設置

如需容許全部資源均可以訪問的資源,能夠如此設置:

Access-Control-Allow-Origin: *

如需容許https://developer.mozilla.org訪問您的資源,能夠設置:

Access-Control-Allow-Origin: https://developer.mozilla.org

Node.js 設置header解決跨域問題

//也可單獨於某個請求中設置相應頭
app.all('*', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
    next();
});

CORS和緩存

若是服務器未使用「*」,而是指定了一個域,那麼爲了向客戶端代表服務器的返回會根據Origin請求頭而有所不一樣,必須在Vary響應頭中包含Origin

Access-Control-Allow-Origin: https://developer.mozilla.org
Vary: Origin

 

 相關鏈接分享

跨域資源共享 CORS 詳解  - 阮一峯

HTTP Headers  - MDN

相關文章
相關標籤/搜索