Url
的通常格式: javascript
協議 + 域名(子域名 + 主域名) + 端口號 + 資源地址
java
示例:git
https://www.dustyblog.cn:8080/say/Hello
是由github
https
+ www
+ dustyblog.cn
+ 8080
+ say/Hello
組成。spring
只要協議,子域名,主域名,端口號這四項組成部分中有一項不一樣,就能夠認爲是不一樣的域,不一樣的域之間互相訪問資源,就被稱之爲跨域。
@RequestMapping("/demo") @RestController public class CorsTestController { @GetMapping("/sayHello") public String sayHello() { return "hello world !"; } }
瀏覽器打開localhost:8080/demo/sayHellosegmentfault
能夠打印出「hello world」跨域
以Chrome爲例:
var token= "LtSFVqKxvpS1nPARxS2lpUs2Q2IpGstidMrS8zMhNV3rT7RKnhLN6d2FFirkVEzVIeexgEHgI/PtnynGqjZlyGkJa4+zYIXxtDMoK/N+AB6wtsskYXereH3AR8kWErwIRvx+UOFveH3dgmdw1347SYjbL/ilGKX5xkoZCbfb1f0=,LZkg22zbNsUoHAgAUapeBn541X5OHUK7rLVNHsHWDM/BA4DCIP1f/3Bnu4GAElQU6cds/0fg9Li5cSPHe8pyhr1Ii/TNcUYxqHMf9bHyD6ugwOFTfvlmtp6RDopVrpG24RSjJbWy2kUOOjjk5uv6FUTmbrSTVoBEzAXYKZMM2m4=,R4QeD2psvrTr8tkBTjnnfUBw+YR4di+GToGjWYeR7qZk9hldUVLlZUsEEPWjtBpz+UURVmplIn5WM9Ge29ft5aS4oKDdPlIH8kWNIs9Y3r9TgH3MnSUTGrgayaNniY9Ji5wNZiZ9cE2CFzlxoyuZxOcSVfOxUw70ty0ukLVM/78="; var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://127.0.0.1:8080/demo/sayHello'); xhr.setRequestHeader("x-access-token",token); xhr.send(null); xhr.onload = function(e) { var xhr = e.target; console.log(xhr.responseText); }
Access to XMLHttpRequest at 'http://127.0.0.1:8080/demo/sayHello' from origin 'https://blog.csdn.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
該結果代表:該請求在https://blog.csdn.net
域名下請求失敗!瀏覽器
CORS
全稱爲Cross Origin Resource Sharing
(跨域資源共享), 每個頁面須要返回一個名爲Access-Control-Allow-Origin
的http頭來容許外域的站點訪問,你能夠僅僅暴露有限的資源和有限的外域站點訪問。
咱們能夠理解爲:若是一個請求須要容許跨域訪問,則須要在http
頭中設置Access-Control-Allow-Origin
來決定須要容許哪些站點來訪問。如假設須要容許https://www.dustyblog.c這個站點的請求跨域,則能夠設置:緩存
Access-Control-Allow-Origin:https://www.dustyblog.cn。
springboot
@CrossOrigin
註解Controller
上使用@CrossOrigin
註解該類下的全部接口均可以經過跨域訪問
@RequestMapping("/demo2") @RestController //@CrossOrigin //全部域名都可訪問該類下全部接口 @CrossOrigin("https://blog.csdn.net") // 只有指定域名能夠訪問該類下全部接口 public class CorsTest2Controller { @GetMapping("/sayHello") public String sayHello() { return "hello world --- 2"; } }
這裏指定當前的CorsTest2Controller
中全部的方法能夠處理https://csdn.net
域上的請求,這裏能夠測試一下:
/demo2
,請區別於1.2 案例中的/demo
)var token= "LtSFVqKxvpS1nPARxS2lpUs2Q2IpGstidMrS8zMhNV3rT7RKnhLN6d2FFirkVEzVIeexgEHgI/PtnynGqjZlyGkJa4+zYIXxtDMoK/N+AB6wtsskYXereH3AR8kWErwIRvx+UOFveH3dgmdw1347SYjbL/ilGKX5xkoZCbfb1f0=,LZkg22zbNsUoHAgAUapeBn541X5OHUK7rLVNHsHWDM/BA4DCIP1f/3Bnu4GAElQU6cds/0fg9Li5cSPHe8pyhr1Ii/TNcUYxqHMf9bHyD6ugwOFTfvlmtp6RDopVrpG24RSjJbWy2kUOOjjk5uv6FUTmbrSTVoBEzAXYKZMM2m4=,R4QeD2psvrTr8tkBTjnnfUBw+YR4di+GToGjWYeR7qZk9hldUVLlZUsEEPWjtBpz+UURVmplIn5WM9Ge29ft5aS4oKDdPlIH8kWNIs9Y3r9TgH3MnSUTGrgayaNniY9Ji5wNZiZ9cE2CFzlxoyuZxOcSVfOxUw70ty0ukLVM/78="; var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://127.0.0.1:8080/demo2/sayHello'); xhr.setRequestHeader("x-access-token",token); xhr.send(null); xhr.onload = function(e) { var xhr = e.target; console.log(xhr.responseText); }
返回結果:
ƒ (e) { var xhr = e.target; console.log(xhr.responseText); } VM156:8 hello world --- 2
說明跨域成功!
OPTIONS http://127.0.0.1:8080/demo2/sayHello 403 (anonymous) Access to XMLHttpRequest at 'http://127.0.0.1:8080/demo2/sayHello' from origin 'http://www.cnblogs.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
說明跨域失敗!證實該方案成功指定了部分域名能跨域!
WebMvcConfigurer
CorsConfig.java
:/** * 跨域配置 */ @Configuration public class CorsConfig implements WebMvcConfigurer { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"). allowedOrigins("https://www.dustyblog.cn"). //容許跨域的域名,能夠用*表示容許任何域名使用 allowedMethods("*"). //容許任何方法(post、get等) allowedHeaders("*"). //容許任何請求頭 allowCredentials(true). //帶上cookie信息 exposedHeaders(HttpHeaders.SET_COOKIE).maxAge(3600L); //maxAge(3600)代表在3600秒內,不須要再發送預檢驗請求,能夠緩存該結果 } }; } }
var token= "LtSFVqKxvpS1nPARxS2lpUs2Q2IpGstidMrS8zMhNV3rT7RKnhLN6d2FFirkVEzVIeexgEHgI/PtnynGqjZlyGkJa4+zYIXxtDMoK/N+AB6wtsskYXereH3AR8kWErwIRvx+UOFveH3dgmdw1347SYjbL/ilGKX5xkoZCbfb1f0=,LZkg22zbNsUoHAgAUapeBn541X5OHUK7rLVNHsHWDM/BA4DCIP1f/3Bnu4GAElQU6cds/0fg9Li5cSPHe8pyhr1Ii/TNcUYxqHMf9bHyD6ugwOFTfvlmtp6RDopVrpG24RSjJbWy2kUOOjjk5uv6FUTmbrSTVoBEzAXYKZMM2m4=,R4QeD2psvrTr8tkBTjnnfUBw+YR4di+GToGjWYeR7qZk9hldUVLlZUsEEPWjtBpz+UURVmplIn5WM9Ge29ft5aS4oKDdPlIH8kWNIs9Y3r9TgH3MnSUTGrgayaNniY9Ji5wNZiZ9cE2CFzlxoyuZxOcSVfOxUw70ty0ukLVM/78="; var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://127.0.0.1:8080/demo3/sayHello'); xhr.setRequestHeader("x-access-token",token); xhr.send(null); xhr.onload = function(e) { var xhr = e.target; console.log(xhr.responseText); }
輸出結果
ƒ (e) { var xhr = e.target; console.log(xhr.responseText); } VM433:8 hello world --- 3
說明跨域成功,換個網址如https://www.baidu.com測試依舊出現須要跨域的錯誤提示,證實該配置正確,該方案測試經過。
經過實現Fiter
接口在請求中添加一些Header
來解決跨域的問題
@Component public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse res = (HttpServletResponse) response; res.addHeader("Access-Control-Allow-Credentials", "true"); res.addHeader("Access-Control-Allow-Origin", "*"); res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN"); if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) { response.getWriter().println("ok"); return; } chain.doFilter(request, response); } @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) throws ServletException { } }
風塵博客公衆號: