出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的。javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。
协议,主机(ip),端口号,这三个有一个不同就属于跨域访问
跨域访问前端和后端不设置一些东西的话,不能访问
当前页面URL | 被请求页面URL | 是否跨域 | 原因 |
---|---|---|---|
http://www.test.com/ | http://www.test.com/index.html | 否 | 同源(协议、域名、端口) |
http://www.test.com/ | https://www.test.com/index.html | 跨域 | 协议不同 |
http://www.test.com/ | http://www.test1.com/ | 跨域 | 域名不同 |
http://www.test.com:8080/ | http://www.test.com:8081/ | 跨域 | 端口不同 |
比较常用的3种
1.Jsonp 最早的解决方案,利用script标签可以跨域的原理实现。
前端解决方案,不知道好不好用,
2. nginx反向代理
思路是:利用nginx反向代理把跨域改为不跨域,支持各种请求方式
缺点:需要在nginx进行额外配置,语义不清晰
规范化的跨域请求解决方案,安全可靠。
优势:
在服务端进行控制是否允许跨域,可自定义规则
缺点:
会产生额外请求
cors是一种机制,这种机制通过在http头部添加字段,
通常情况下,web应用A告诉浏览器,自己有权限访问应用B
CORS的标准定义是:通过设置http头部字段,让客户端有资格跨域访问资源。通过服务器的验证和授权之后,浏览器有责任支持这些http头部字段并且确保能够正确的施加限制。
JSON与CORS的比较
1.JSONP 只能实现 GET 请求,而 CORS 支持所有类型的 HTTP 请求
2.使用 CORS ,开发者可以是使用普通的 XMLHttpRequest 发起请求和获取数据,比起 JSONP 有更好的错误处理
3.虽然绝大多数现代的浏览器都已经支持 CORS,但是 CORS 的兼容性比不上 JSONP,一些比较老的浏览器只支持 JSONP
- @CrossOrigin(origins = "*")
- @Slf4j
- @RestController
- public class EmployeeController {
-
- }
- @RestController
- @CrossOrigin(origins = "*")//实行全局跨域
- @Slf4j
- public class HelloController {
- @Reference
- private HelloService helloService;
-
- @GetMapping(value = "/hello",name = "测试")
- public ResponseEntity hello(@RequestParam String name){
- String hello = helloService.hello(name);
- return ResponseEntity.ok(hello);
- }
-
- }
- @RestController
- public class HiController {
-
- @Reference
- private HiService hiService;
-
- @GetMapping(value = "/hi")
- public ResponseEntity hiName(@RequestParam String name){
- String respHiName = hiService.hiName(name);
- return ResponseEntity.ok(respHiName);
- }
-
- }
我们可以看到,后端有连个controller HiController中没有添加@CrossOrigin(origins = "*")
跨域访问试试看
前端:
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Documenttitle>
- <script src="js/axios-0.18.0.js">script>
- head>
- <body>
- <button id="hello">hellobutton>
- <button id="hi">hibutton>
- <script>
- var hello = document.getElementById("hello");
- var hi = document.getElementById("hi");
- hello.onclick = function(){
- axios.get("http://localhost:8082/hello?name=张三")
- .then(resp=>{
- alert(resp.data);
- })
- }
- hi.onclick = function(){
- axios.get("http://localhost:8082/hi?name=张三")
- .then(resp=>{
- alert(resp.data);
- })
- }
- script>
- body>
- html>
首先肯定是跨域,点击hi 的话会报错,当hiController中添加@CrossOrigin(origins = "*")
就ok了
如果说你有好多Controller 每一个都要配置,那么不值当的,所有可以用这种方法
- @Configuration
- public class DemoWebMvcConfig implements WebMvcConfigurer {
- @Override
- public void addCorsMappings(CorsRegistry registry) {
- registry.addMapping("/**") // 匹配了所有的URL
- .allowedHeaders("*") // 允许跨域请求包含任意的头信息
- .allowedMethods("*") // 设置允许的方法
- .allowedOrigins("*") // 设置允许跨域请求的域名
- .allowCredentials(false); // 是否允许证书,默认false
- }
- }