1:构造跨域请求
用本地tomcat跑程序,其中一个jsp文件为:
<!DOCTYPE html>
<html>
<head>
<title>Hello CORS</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
$(document).ready(function() {
$.ajax({
url: "http://192.168.1.103:8080/user/testcors",
method: "POST",
contentType: "application/json; charset=utf-8"
}).then(function(data, status, jqxhr) {
alert(data)
});
});
</script>
</head>
<body>
<h1>小红</h1>
</body>
</html>
在浏览器访问这个文件就会报错
http://192.168.1.103:8080/user/testcors 403 ()
Failed to load http://192.168.1.103:8080/user/testcors: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 403.
这是因为产生了跨域
如果该jsp改为:
<!DOCTYPE html>
<html>
<head>
<title>Hello CORS</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
$(document).ready(function() {
$.ajax({
url: "http://localhost:8080/user/testcors",
method: "POST",
contentType: "application/json; charset=utf-8"
}).then(function(data, status, jqxhr) {
alert(data)
});
});
</script>
</head>
<body>
<h1>小红</h1>
</body>
</html>
这是能正常访问的 这表明用本机ip地址ajax调用接口是会产生跨域,如果用localhost来调用就不会。
2:解决办法
先将jsp代码改为
<!DOCTYPE html>
<html>
<head>
<title>Hello CORS</title>
<script src="${ctx}/static/js/jquery.min.js"></script>
<script>
$(document).ready(function() {
$.ajax({
url: "http://192.168.1.103:8080/user/testcors",
method: "POST",
}).then(function(data, status, jqxhr) {
alert(data)
});
});
</script>
</head>
<body>
<h1>小红</h1>
</body>
</html>
主要有五种方法可以解决:
第一种:使用拦截器Interceptor来进行处理
java代码如下
package com.xcd.zc.config;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public class CorsInterceptor implements HandlerInterceptor {
/**
*
* 在业务处理器处理请求之前被调用 如果返回false
* 从当前的拦截器往回执行所有拦截器的afterCompletion(),
* 再退出拦截器链, 如果返回true 执行下一个拦截器,
* 直到所有的拦截器都执行完毕 再执行被拦截的Controller
* 然后进入拦截器链,
* 从最后一个拦截器往回执行所有的postHandle()
* 接着再从最后一个拦截器往回执行所有的afterCompletion()
*
* @param request
*
* @param response
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept");
return true;
}
// 在业务处理器处理请求执行完成后,生成视图之前执行的动作
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
/**
*
* 在DispatcherServlet完全处理完请求后被调用
* 当有拦截器抛出异常时,
* 会从当前拦截器往回执行所有的拦截器的afterCompletion()
*
* @param request
*
* @param response
*
* @param handler
*
*/
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
}
}
然后载context xml里面加入
<!--<mvc:interceptors>-->
<!--<mvc:interceptor>-->
<!--<mvc:mapping path="/**" />-->
<!--<bean class="com.xcd.zc.config.CorsInterceptor">-->
<!--</bean>-->
<!--</mvc:interceptor>-->
<!--</mvc:interceptors>-->
第二种:通过在context xml中加入
<mvc:cors>
<mvc:mapping path="/**" />
</mvc:cors>
来达到全局控制 注意这个是4.2之后才会有的
所以
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
这个要写成4.2以上,或者是写成
http://www.springframework.org/schema/mvc/spring-mvc.xsd
第三种:配置全局config类
代码如下
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*") ;
}
}
但是这个我试了 一直没成功 谁懂的可以留言
第四种:在controller上方加注解 @CrossOrigin 来达到这个controller下面的方法都可以跨域请求 这个要求spring 版本是 4.2以上
第五种:在方法上方加注解 @CrossOrigin 来达到这个controller下面的方法都可以跨域请求 这个要求spring 版本是 4.2以上