javascript
Springboot 利用CORS 解决跨域问题
什么是跨域
首先我們先用springboot 建立1個簡單的API, 它返回1個json
package com.example.demo_api_cors.controller;import com.example.demo_api_cors.dto.ValueDto; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController;@RestController public class demoController {@RequestMapping("/getValue")@ResponseBodypublic ValueDto cors1(){return new ValueDto(0, "new Value");} }然后啟動這個springboot, 端口是8081
可以看到, 我們可以在瀏覽器地址欄輸入 url http://localhost:8081/getValue
來訪問這個api, 其中localhost 就是域名, 8081就是端口
打開debug mode, 可以見到Response Header的信息, 如上圖籃圈中。
然后我們在建立1個springboot 項目, 使用8082 這個端口, 嘗試在項目中的某個html文件調用上面這個api
<!doctype html> <html> <head><script src="js/angular_161/angular.min.js"></script> </head><body><div ng-app="myApp" ng-controller="myCtrl"><h1>value is {{value}}</h1></div><script>var app = angular.module('myApp', []);app.controller('myCtrl', function($scope, $http) {$scope.value ='old value'$http({url: "http://localhost:8081/getValue",method:"get",}).then(function (result) {//正確請求成功時處理$scope.value = result.data.value;}).catch(function (result) { //捕捉錯誤處理alert(result);});});</script></body> </html>執行時, 瀏覽器會顯示下面的錯誤
Access to XMLHttpRequest at ‘http://localhost:8081/getValue’ from origin ‘http://localhost:8082’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
其實錯誤信息寫得很清楚,
就是告訴你發生了跨域行為, 從origin http://localhost:8082 訪問另1個域的接口 http://localhost:8081/getValue, 這個行為被CORS policy禁止了, 因為respone header 沒有 ‘Access-Control-Allow-Origin’ 這個item。
其實兩個service 的域名都是localhost, 但是他們端口不一樣, 瀏覽器還是認為跨域了。
跨域的定義
其實, 對于http://localhost:8081/getValue 這個api, 直接在瀏覽器地址欄輸入訪問是沒有問題的,沒有跨域。
用命令行curl 去訪問, 也沒有問題, 沒有跨域。
用postman 訪問, 也不會跨域。
在java/python的后臺訪問, 也不會跨域。
跨域是瀏覽器的行為,因為瀏覽器做了限制,如果你能修改瀏覽器的代碼, 也可以取消跨域限制。
只有在瀏覽器的訪問的html頁面中, 調用另1個域名或另個端口api, 就會產生跨域問題。
也就是如果在同1個springboot中html調用后臺的接口是沒有跨域的, 前后端分離就很可能會跨域。
在html中引用靜態資源(js, css, img)也不會產生跨域。
只有在ajax調用api才會有跨域問題。
解決方法一, jsonp
因為靜態資源不會產生跨域, 那么在后臺中返回一段js腳本, 然后在html中靜態引入,返回時再調用js里的callback函數,來欺騙瀏覽器。 這種技術就是jsonp。 jsonp只支持get接口的跨域。
spring 在5.1中拋棄了jsonp這個古老的解決跨域方法。 這里不討論了。
解決方法二, CORS 解決跨域
這個方法是目前正統的方法, 原理也很簡單, 上面錯誤信息也作了提示, 只要在reponse 中加入1個header item ‘Access-Control-Allow-Origin’ , 告訴瀏覽器這個接口支持跨域訪問, 問題解決。
所以必須在api的項目修改接口。
在Controller中加入CrossOrigin(origins="*") 這個直接。
- 就是代表允許所有源主機跨域訪問, 也可以增加參數指定 get 還是 post, 不寫就默認全部
重新啟動api項目, 問題解決。
檢查 Response Headers, 果然多了Access-Control-Allow-Origin 這個header
總結
以上是生活随笔為你收集整理的Springboot 利用CORS 解决跨域问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 笔记 - AliCloud 云上安全防护
- 下一篇: JDK环境下利用记事本对java文件进行