跨域解决方案之CORS
目錄
1.什么叫做跨域請(qǐng)求
2.跨域調(diào)用測(cè)試
3.解決方案CORS跨域
(1)概述
(2)請(qǐng)求過程
(3)解決辦法
(4)SpringMVC跨域注解
1.什么叫做跨域請(qǐng)求
跨域是指通過js在不同的域之間進(jìn)行數(shù)據(jù)傳輸或通信,比如用ajax向一個(gè)不同的域請(qǐng)求數(shù)據(jù),或者通過js獲取頁面中不同域的框架中(iframe)的數(shù)據(jù)。只要協(xié)議、域名、端口有任何一個(gè)不同,都被當(dāng)作是不同的域。
2.跨域調(diào)用測(cè)試
(1)啟動(dòng)一個(gè)服務(wù),端口號(hào)為8080
@RestController public class CORSController { ?@RequestMapping("findName")public Map findName() {Map map = new HashMap();map.put("name", "張三");map.put("age", 18);return map;} }(2)啟動(dòng)另一個(gè)服務(wù),端口號(hào)為9090
test.html
<script src="js/angular.js"></script> ? <script>var app=angular.module("myApp",[]);app.controller("myController",function ($http,$scope) {$scope.findName=function () {$http.get('http://localhost:8080/findName.do').success(function (response) {$scope.person=response;})}}) </script> <body ng-app="myApp" ng-controller="myController" ng-init="findName()"> ? {{person.name}}<br/> {{person.age}}當(dāng)9090的服務(wù)調(diào)用8080的findName方法時(shí),會(huì)報(bào)如下的錯(cuò)誤
Failed to load http://localhost:8080/findName.do: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9090' is therefore not allowed access. The response had HTTP status code 404.3.解決方案CORS跨域
(1)概述
CORS是一個(gè)W3C標(biāo)準(zhǔn),全稱是"跨域資源共享"(Cross-origin resource sharing)。CORS需要瀏覽器和服務(wù)器同時(shí)支持。目前,所有瀏覽器都支持該功能,IE瀏覽器不能低于IE10。
它允許瀏覽器向跨源服務(wù)器,發(fā)出XMLHttpRequest請(qǐng)求,從而克服了AJAX只能同源使用的限制。整個(gè)CORS通信過程,都是瀏覽器自動(dòng)完成,不需要用戶參與。對(duì)于開發(fā)者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發(fā)現(xiàn)AJAX請(qǐng)求跨源,就會(huì)自動(dòng)添加一些附加的頭信息,有時(shí)還會(huì)多出一次附加的請(qǐng)求,但用戶不會(huì)有感覺。因此,實(shí)現(xiàn)CORS通信的關(guān)鍵是服務(wù)器。只要服務(wù)器實(shí)現(xiàn)了CORS接口,就可以跨源通信。
(2)請(qǐng)求過程
請(qǐng)求過程如下圖:
Preflight Request:
然后服務(wù)器端給我們返回一個(gè)Preflight Response
(3)解決辦法
Access-Control-Allow-Origin
Access-Control-Allow-Origin是HTML5中定義的一種解決資源跨域的策略。
他是通過服務(wù)器端返回帶有Access-Control-Allow-Origin標(biāo)識(shí)的Response header,用來解決資源的跨域權(quán)限問題。
使用方法,在response添加 Access-Control-Allow-Origin,例如
Access-Control-Allow-Origin:www.google.com也可以設(shè)置為 * 表示該資源誰都可以用
?
更改8080端口的controller方法
@RestController public class CORSController { ?@RequestMapping("findName")public Map findName(HttpServletResponse response) {response.setHeader("Access-Control-Allow-Origin", "http://localhost:9090");?Map map = new HashMap();map.put("name", "張三");map.put("age", 18);return map;} }重新訪問http://localhost:9090/test.html,可以跨域請(qǐng)求成功
如果要操作cookie,后端controller層加如下代碼
? response.setHeader("Access-Control-Allow-Origin", "http://localhost:9090");//此時(shí)Access-Control-Allow-Origin無法用*匹配任意地址,必須指定精確的路徑response.setHeader("Access-Control-Allow-Credentials", "true");前端必須在AJAX請(qǐng)求中打開withCredentials屬性
$http.get('http://localhost:8080/cors01/findName.do',{'withCredentials':true})請(qǐng)求頭如下:
響應(yīng)頭如下:
(4)SpringMVC跨域注解
springMVC的版本在4.2或以上版本,可以使用注解實(shí)現(xiàn)跨域, 我們只需要在需要跨域的方法上添加注解@CrossOrigin即可
@CrossOrigin(origins="http://localhost:9090",allowCredentials="true")allowCredentials="true" 可以缺省
?
總結(jié)
以上是生活随笔為你收集整理的跨域解决方案之CORS的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring任务调度之Spring-Ta
- 下一篇: 微信二维码支付快速入门