springboot之跨域访问cros,@CrossOrigin注解-优快云博客
要点:
同源,
就是指请求的资源url和目前文件来源url的协议、域名和端口都相同。同源即同域,两者意思相同
浏览器的同源策略是指:js脚本在未经允许的情况下,不能够访问其他域下的内容,以保证用户信息的安全,防止恶意的网站窃取数据。
3、限制跨域 ajax 请求,是为了保护被跨域请求的服务器中数据库用户信息,更加准确地说是跨域请求能发出去,服务器端能收到请求并正常返回结果,但是结果被浏览器拦截了
特殊:script标签,img标签,以及link标签可以链接其他域中的资源, 因为这些标签不能通过相应的结果来进行安全问题的操作
注:跨源请求的本质是请求别人的信息,所以能否跨域请求,是由被请求的服务器的设置决定的。
1、什么是跨域访问
从 A 向 B 发请求,如果他们的url非同源,直接访问就会造成跨域问题。跨域是客户端问题,跨域请求有两种情况:
①普通的图片、css文件请求,不报错
②发送Ajax请求,报错
发起跨域请求 --> 浏览器在请求的header上添加origin字段 --> 请求成功发送到服务器 --> 服务器将数据返回给浏览器 --> 服务器返回的响应头中,没有告诉浏览器哪个域名可以访问这些数据(没有设置 Access-Control-Allow-Origin)--> 浏览器将丢弃数据,抛出错误
2、为什么前后端分离项目会产生跨域问题
前后端分离的应用,前端、后端是2个独立的应用,运行在不同端口。在浏览器看来,是不同的域,由于浏览器同源策略的限制,导致不同源之间的通信。前端页面中的ajax请求后端接口,即跨域访问。
3、跨域过程分析
浏览器对前端页面和后台交互url判断,若同源,则直接发送数据请求;若不同源,则发送跨域请求 ---->
判断跨域请求。非简单请求:浏览器会帮我们自动触发预检请求,用于确认请求内容是否符合服务端的要求,如果符合,在进行正式的请求。简单请求:直接发出正常请求。---->
服务器收到浏览器跨域请求后,根据自身配置返回对应文件头。若未配置允许跨域,即文件头里不包含 Access-Control-Allow-origin 字段,若配置过域名,则返回 Access-Control-Allow-origin + 对应配置规则里的域名的方式。 ---->
浏览器根据接收到的响应头里的 Access-Control-Allow-origin 字段判断,若无该字段,说明不允许跨域,抛出一个错误;若有该字段,对字段内容和当前域名做比对,如果同源,即允许跨域,浏览器接受该响应;若不同源,即该域名不可跨域,浏览器不接受该响应,并抛出一个错误。
-----------------------------
两种跨域的方法:
1、配置全局跨域访问
在项目路径下创建config文件夹,在config文件夹下创建CrosConfig类实现WebConfigConfigurer
@Configuration
public class CrosConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") //**匹配的是我们所有后台的路径,代表后台共享了什么资源
.allowedOrigins("http://localhost:8082") //匹配的前台的服务器地址
.maxAge(300 * 1000)
.allowedHeaders("*")
.allowedMethods("*"); //允许的前台的请求方式
}
}
或者:
使用的Spring Boot,声明一个WebMvcConfigurer bean,如下所示:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
2、@CrossOrigin注解
作用:
在controller上添加@CrossOrigin注解用来开启跨域请求,让其他域的请求可以访问该controller,否则所有其他域的访问会全部被拒绝。
详解:
origin属性:允许可访问的域列表
maxAge:准备响应前的缓存持续的最大时间(以秒为单位)
①@CrossOrigin注解用在类上
整个类的方法都可以被允许的域访问
@Controller
@CrossOrigin("http://localhost:8082")
//@RequestMapping("/emp")
public class EmpController {
@Autowired
private IEmpService empService;
@RequestMapping("/getConformEmp")
@ResponseBody
public String getConformEmp(@RequestBody Map<String,String> map) {
System.out.println(map);
String name = map.get("name");
String age = map.get("age");
return name + "今年" + age + "岁了!";
}
}
②注解用在方法上
有注解的方法可以被指定的域访问
补充深入了解和原理:
Spring CORS 跨域使用与原理(@CrossOrigin注解,Java配置类方式,xml方式)-优快云博客