什麼是JS跨域、以及CORS解決方案

一、什麼是JS跨域

1、跨域:在瞭解跨域之前,首先要知道什麼是同源策略(same-origin policy)。簡單來講同源策略就是瀏覽器爲了保證用戶信息的安全,防止惡意的網站竊取數據,禁止不同域之間的JS進行交互。對於瀏覽器而言只要域名、協議、端口其中一個不同就會引發同源策略,從而限制他們之間如下的交互行爲:
 

2、JS跨域:指通過js在不同的域之間進行數據傳輸或通信,比如用ajax向一個不同的域請求數據,或者通過js獲取頁面中不同域的框架中(iframe)的數據。

那什麼是不同的域呢?只要協議域名端口有任何一個不同,都被當作是不同的域。

舉例:

域名 說明 是否允許訪問
http://www.example.com 協議不同 不允許訪問
https://www.example.com
http://www.example.com:8080 端口不同 不允許訪問
http://www.example.com:3306
http://www.example.com 域名不同 不允許訪問
http://www.baidu.com
http://www.example.com/a.js 相同域下同一文件夾 允許訪問
http://www.example.com/b.js
http://www.example.com/a.js 相同域下不同文件夾 允許訪問
http://www.example.com/js/a.js

注意

        1、ip相同,域名不同,也是跨域。 

        2、如果是協議和端口造成的跨域問題“前臺”是無能爲力的。

3、爲什麼要限制跨域訪問:安全問題。

如果一個網頁可以隨意地訪問另外一個網站的資源,那麼就有可能在客戶完全不知情的情況下出現安全問題。比如下面的操作就有安全問題:

1.用戶訪問www.mybank.com,登陸並進行網銀操作,這時cookie啥的都生成並存放在瀏覽器;

2.用戶突然想起件事,並迷迷糊糊的訪問了一個邪惡的網站www.xiee.com;

3.這時該網站就可以在它的頁面中,拿到銀行的cookie,比如用戶名,登陸token等,然後發起對www.mybank.com的操作;

4.如果這時瀏覽器不予限制,並且銀行也沒有做響應的安全處理的話,那麼用戶的信息有可能就這麼泄露了。


4、爲什麼要跨域

既然有安全問題,那爲什麼又要跨域呢? 有時公司內部有多個不同的子域,比如一個是cart.jd.com ,而應用是放在app.jd.com , 這時想從 app.jd.com去訪問 cart.jd.com 的資源就屬於跨域。

 

二、解決方案

使用跨域資源共享(CORS)來跨域

CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。CORS需要瀏覽器和服務器同時支持。目前,所有瀏覽器都支持該功能,IE瀏覽器不能低於IE10。

它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對於開發者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感覺。因此,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信。

只需要在後臺中加上響應頭來允許域請求!在被請求的Response header中加入以下設置,就可以實現跨域訪問了!


//指定允許其他域名訪問

'Access-Control-Allow-Origin:*'//或指定域

//響應類型

'Access-Control-Allow-Methods:GET,POST'

//響應頭設置

'Access-Control-Allow-Headers:x-requested-with,content-type'

舉例:

  @RequestMapping("/add")
    public Result add(Long id, Integer num) {
        /*CORS*/
        response.setHeader("Access-Control-Allow-Origin", "http://localhost:9105");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        
        /* 你的邏輯代碼*/
}

Spring Framework 4.2 GA爲CORS提供了第一類支持,使您比通常的基於過濾器的解決方案更容易和更強大地配置它。所以springMVC的版本要在4.2或以上版本才支持@CrossOrigin。

@CrossOrigin()註解來替代上面的兩行話 參考@CrossOrigin()詳解
@RequestMapping("/addGoodsToCartList")
    @CrossOrigin(origins = "http://localhost:9105", allowCredentials = "true")//默認是ture
    public Result addGoodsToCartList(Long itemId, Integer num) {
        /*CORS*/
       /* response.setHeader("Access-Control-Allow-Origin", "http://localhost:9105");
        response.setHeader("Access-Control-Allow-Credentials", "true");*/

       /*邏輯代碼*/
}

 

Access-Control-Allow-Origin

Access-Control-Allow-OriginHTML5中定義的一種解決資源跨域的策略。

他是通過服務器端返回帶有Access-Control-Allow-Origin標識的Response header,用來解決資源的跨域權限問題。

 使用方法:在response添加 Access-Control-Allow-Origin,例如

Access-Control-Allow-Origin:www.google.com

也可以設置爲 * 表示該資源誰都可以用

前端JS代碼

//添加商品到購物車

$scope.addToCart=function(){

    $http.get('http://localhost:9107/cart/addGoodsToCartList.do?itemId='

    + $scope.sku.id +'&num='+$scope.num,{'withCredentials':true}).success(

             function(response){

                 .......             

             }               

    );     

}

調用測試,可以實現跨域了。

CORS請求默認不發送Cookie和HTTP認證信息。如果要把Cookie發到服務器,一方面要服務器同意,指定Access-Control-Allow-Credentials字段。另一方面,開發者必須在AJAX請求中打開withCredentials屬性。否則,即使服務器同意發送Cookie,瀏覽器也不會發送。或者,服務器要求設置Cookie,瀏覽器也不會處理。

 

 

 

 

 

文主要介紹CORS解決方案

其他解決方案請參考 js處理的8種跨域方法

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章