這里說的js跨域是指通過js在不同的域之間進行數據傳輸或通信,比如用ajax向一個不同的域請求數據,或者通過js獲取頁面中不同域的框架中(iframe)的數據。只要協議、域名、端口有任何一個不同,都被當作是不同的域。
一個工程通過js訪問另一個工程時,會報以下錯誤
XMLHttpRequest cannot load
http://localhost:9107/cart/addGoodsToCartList.do?itemId=112344&num=1.
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9100' is therefore not allowed access. The response had HTTP status code 400.
跨域解決方案CORS
CORS是一個W3C標准,全稱是"跨域資源共享"(Cross-origin resource sharing)。CORS需要瀏覽器和服務器同時支持。目前,所有瀏覽器都支持該功能,IE瀏覽器不能低於IE10。它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對於開發者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感覺。因此,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信。
請求過程如下圖:

Preflight Request:

然后服務器端給我們返回一個Preflight Response

解決
(1) 在方法中添加以下代碼
Access-Control-Allow-Origin
Access-Control-Allow-Origin是HTML5中定義的一種解決資源跨域的策略。
他是通過服務器端返回帶有Access-Control-Allow-Origin標識的Response header,用來解決資源的跨域權限問題。
http://localhost:9105:表示允許跨域的資源,*表示所有資源都允許跨域
response.setHeader("Access-Control-Allow-Origin", "http://localhost:9105");
response.setHeader("Access-Control-Allow-Credentials", "true");
(2) 修改js的代碼(angular.js)
$scope.addToCart=function(){ $http.get('http://localhost:9107/cart/addGoodsToCartList.do?itemId=' + $scope.sku.id +'&num='+$scope.num,{'withCredentials':true}).success( function(response){ ....... } ); }
SpringMVC跨域注解
springMVC的版本在4.2或以上版本,可以使用注解實現跨域, 我們只需要在需要跨域的方法上添加注解@CrossOrigin即可
PS:我的是JDK1.7,沒成功,估計要JDK1.8以上吧,沒去測試
@CrossOrigin(origins="http://localhost:9105",allowCredentials="true")
// response.setHeader("Access-Control-Allow-Origin", "http://localhost:9105");
// response.setHeader("Access-Control-Allow-Credentials", "true");
