做小程序的时候,有个别的接口,需要提供给小程序服务以外的推广页使用,推广页域名与小程序后端服务接口域名产生了跨域问题,查了部分资料后,有两种解决方案。
首先说一下跨域问题的原因:
跨域是指:浏览器A从服务器B获取的静态资源,包括Html、Css、Js,然后在Js中通过Ajax访问C服务器的静态资源或请求。即:浏览器A从B服务器拿的资源,资源中想访问服务器C的资源。
同源策略是指:浏览器A从服务器B获取的静态资源,包括Html、Css、Js,为了用户安全,浏览器加了限制,其中的Js通过Ajax只能访问B服务器的静态资源或请求。即:浏览器A从哪拿的资源,那资源中就只能访问哪。
同源是指:同一个请求协议(如:Http或Https)、同一个Ip、同一个端口,3个全部相同,即为同源。
解决方案有很多,本文只记录cors的方案。
SpringBoot2.x配置Cors
SpringBoot2.x主要提供了两种方式来支持Cors,如下:
| 方式 |作用范围| 说明 |
|:-------:|:-------------:|:-----:|
| @CrossOrigin |一个Controller中全部接口或是其中一个特定的接口| 配置、定制特定的请求接口 |
|WebMvcConfigurer对象| 全部接口 |适用于全局配置|
第一种: 使用@CrossOrigin注解
代码实例
@RestController
@RequestMapping(value = "/api")
@CrossOrigin
public class UsersController{
@Autowired
private UsersService usersService;
@PostMapping("userInfo/{openid}")
@CrossOrigin
public User getUserInfo(@PathVariable String openid) {
return userService.get(openid);
}
}
其中,@CrossOrigin注解可以使用以下参数
| 名称 |类型| 范围 | 必填 |请求头字段 |
|:-------:|:-------------:|:-----:|:-----:|:-----:|
| value |String数组 |类或方法|是|Access-Control-Allow-Origin|
| origins |String数组 |类或方法|是,同value,可以二选一|Access-Control-Allow-Origin|
| methods |String数组 |类或接口|是|Access-Control-Allow-Methods|
| maxAge | long | 类或接口 | 否 | Access-Control-Max-Age |
| allowCredentials |String | 类或接口 | 否 | Access-Control-Allow-Credentials |
| allowedHeaders | String数组 | 类或接口 | 否 | Access-Control-Request-Headers |
| exposedHeaders | String数组 | 类或接口 | 否 | Access-Control-Expose-Headers |
备注说明
value、origins属性:配置允许访问的源,如: http://anxminise.cc,*表示允许全部的域名
methods属性:配置跨域请求支持的方式,如:GET、POST,且一次性返回全部支持的方式
maxAge属性:配置预检请求的有效时间, 单位是秒,表示:在多长时间内,不需要发出第二次预检请求
allowCredentials属性:配置是否允许发送Cookie,用于 凭证请求, 默认不发送cookie
allowedHeaders属性:配置允许的自定义请求头,用于 预检请求
exposedHeaders属性:配置响应的头信息, 在其中可以设置其他的头信息,不进行配置时, 默认可以获取到Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma字段
第二种: 使用WebMvcConfigurer对象
代码实例
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT","PATCH")
.maxAge(3600);
}
};
}
}
其中,通过相应的方法实现跨域请求的配置
| 方法类 |方法名称| 必填 | 请求头字段 |说明 |
|:-------:|:-------------:|:-----:|:-----:|:-----:|
| CorsRegistry |addMapping | 是 | 无, 非Cors属性, 属于SpringBoot配置 |配置支持跨域的路径|
| CorsRegistration |allowedOrigins | 是 | Access-Control-Allow-Origin |配置允许的源|
| CorsRegistration | allowedMethods | 是 |Access-Control-Allow-Methods| 配置支持跨域请求的方法, 如:GET、POST,一次性返回|
| CorsRegistration | maxAge | 否 | Access-Control-Max-Age | 配置预检请求的有效时间 |
| CorsRegistration |allowCredentials | 否 | Access-Control-Allow-Credentials | 配置是否允许发送Cookie, 用于 凭证请求 |
| CorsRegistration | allowedHeaders | 否 | Access-Control-Request-Headers | 配置允许的自定义请求头, 用于 预检请求 |
| CorsRegistration | exposedHeaders | 否 | Access-Control-Expose-Headers | 配置响应的头信息, 在其中可以设置其他的头信息 |