1、同源策略:阻止一个域的javascript脚本和另外一个域的内容进行交互。同源(即指在同一个域)就是两个页面具有相同的协议(如都是http),域名(如都是www.cat.com,二级域名也不行)和端口号(如都是8080)
2、跨域:一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同
1、cors解决(以下三种方式):先发出一次OPTIONS的预检请求 Preflighted requests 这个请求是用来验证本次请求是否安全的
1)单个接口注解方式
@CrossOrigin(origins = "http://127.0.0.1:8080")
public ApiResult read(@RequestBody IdDTO dto){//业务代码...}
2)增加一个跨域配置类,允许所有域名进行跨域的方式
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", crosConfiguration());
return new CorsFilter(source);
}
public CorsConfiguration crosConfiguration(){
CorsConfiguration config = new CorsConfiguration();
//允许所有域名进行跨域调用
config.addAllowedOrigin("*");
//允许跨越发送cookie
config.setAllowCredentials(true);
//放行全部原始头信息
config.addAllowedHeader("*");
//允许所有请求方法跨域调用
config.addAllowedMethod("*");
return config;
}
}
3)自定义拦截器的方式
@Component
public class RequestInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "86400");
response.setHeader("Access-Control-Allow-Headers", "Authorization");
// 如果是OPTIONS请求则结束
if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
response.setStatus(HttpStatus.NO_CONTENT.value());
return false;
}
return true;
}
}
/** 两个不要同时存在
* WebMvcConfigurationSupport是springboot2.x版本以上的,1.x版本为WebMvcConfigurerAdapter
* WebMvcConfigurationSupport-->不需要返回逻辑视图,可以选择继承此类,此法还需在启动类加@EnableWebMvc
* WebMvcCofigurer-->返回逻辑视图,可以选择实现此方法,重写addInterceptor方法
* 因为继承WebMvcConfigurationSupport会发现Spring Boot的WebMvc自动配置失效(WebMvcAutoConfiguration自动化配置),导致无法视图解析器无法解析并返回到对应的视图
*/
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Autowired
private RequestInterceptor requestInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 跨域拦截器
registry.addInterceptor(requestInterceptor).addPathPatterns("/**");
}
}
//@Configuration
//public class WebConfiguration extends WebMvcConfigurationSupport {
// @Resource
// private RequestInterceptor requestInterceptor;
// @Override
// public void addInterceptors(InterceptorRegistry registry) {
// // 跨域拦截器
// registry.addInterceptor(requestInterceptor).addPathPatterns("/**");
// }
//}
2、nginx代理转发解决
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://192.168.1.6:8080;
}
location /api {
proxy_pass http://192.168.1.6:8090;
}
}
3、jsonp方式解决
1) 代码如下
//客户端,三种都可以
$.ajax({
type: 'GET',
url: 'http://192.168.1.6:8081/index',
dataType : "jsonp",//数据类型为jsonp
jsonp: "jsonpCallback",//服务端用于接收callback调用的function名的参数
success: function(res) {
console.log("########" + res);
},
error: function(){}
});
/*$.getJSON("http://192.168.1.6:8081/index?jsonpCallback=?",
function call(){
console.log();
});*/
//服务端需要打配合
@RestController
public class IndexController {
@RequestMapping("/index")
public String index(HttpServletRequest request){
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("result","index:content");
String jsonpCallback = request.getParameter("jsonpCallback");
return jsonpCallback + "(" + jsonObject.toString() + ")";
}
}