详解Spring Boot 2.0.2+Ajax解决跨域请求的问题
问题描述
后端域名为A.abc.com,前端域名为B.abc.com。浏览器在访问时,会出现跨域访问。浏览器对于javascript的同源策略的限制。
HTTP请求时,请求本身会返回200,但是返回结果不会走success,并且会在浏览器console中提示:
已拦截跨源请求:同源策略禁止读取位于 https://www.baidu.com/ 的远程资源。(原因:CORS 头缺少 ‘Access-Control-Allow-Origin')。
解决方案
1.jsonp
2.引用A站的js
3.Nginx做A站的反向代理
4.后端服务放开跨域请求
其中,以最后两种见常。
详细方案
本文主要描述第四种解决方案:后端服务放开跨域请求。
spring boot中放开跨域请求很简单。
1.增加一个configuration类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* 跨域访问配置
* @author wencst
* @creation 2017年8月18日
*/
@Configuration
public class CustomCORSConfiguration {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}
增加此类以后,非同源http访问可以正常进行了,但是会不会有什么问题呢?
对于大部分网站依然需要使用cookie作为前后端传输数据的媒介,然而默认非同源请求是不携带cookie信息的。
2.服务端允许跨域携带cookie信息
在spring boot2.0.2中,允许跨域设置比较简单,只需增加一个configuration类即可。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* 跨域访问配置
* @author wencst
* @creation 2017年8月18日
*/
@Configuration
public class CustomCORSConfiguration {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addExposedHeader("Content-Type");
corsConfiguration.addExposedHeader( "X-Requested-With");
corsConfiguration.addExposedHeader("accept");
corsConfiguration.addExposedHeader("Origin");
corsConfiguration.addExposedHeader( "Access-Control-Request-Method");
corsConfiguration.addExposedHeader("Access-Control-Request-Headers");
corsConfiguration.setAllowCredentials(true);
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}
增加信息后,在前端依然需要调整AJAX请求,才能在非同源请求中携带cookie信息。
3.前端调整
$.ajax({
url: 'http://beta.roboming.com/api.php?s=/Public/AdminLogin.html',
type: 'POST',
async:true,
xhrFields:{
withCredentials:true
},
data: {
username:userName,
password:pwd
},
success: function(respon){
console.log(respon);
var res=eval(respon);
},
error: function(){
alert('服务器发生错误!');
}
});
此时,当前端向后端服务做跨域请求时,增加
xhrFields:{
withCredentials:true
},
就会带上cookie信息了,同理会带上token/sessionID等等内容。
测试方法
spring boot中增加一个controller
@Controller
public class LoginController {
@RequestMapping(value = "setString")
@ResponseBody
public String setString(HttpServletRequest request, HttpServletResponse response,@RequestParam String value) {
request.getSession().setAttribute("username", value);
return "OK";
}
@RequestMapping(value = "getString")
@ResponseBody
public String getString(HttpServletRequest request, HttpServletResponse response) {
String username = (String)request.getSession().getAttribute("username");
return username;
}
}
增加一个index.html,来访问跨域访问。
<html>
<head>
<meta charset="utf-8">
<title>跨域请求</title>
<script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<button onclick="set()">set</button>
<br><br>
<button onclick="get()">get</button>
<script>
function set(){
$.ajax({
url:'http://wencst.vicp.net/setString?value=10',
xhrFields:{
withCredentials:true
},
success:function(result){
alert(result);
}
});
}
function get(){
$.ajax({
url:'http://wencst.vicp.net/getString',
xhrFields:{
withCredentials:true
},
success:function(result){
alert(result);
}
});
}
</script>
</body>
</html>
html文件可以单独本地访问即可出现效果,并不一定要形成服务访问。
当服务端不允许跨域访问时,html文件访问均报错,并调用失败。
当服务端允许跨域访问时,html请求访问成功。
当服务端开启cookie传递,并在html文件中增加 xhrFields参数时,session生效。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
基于JavaSwing+mysql开发一个学生社团管理系统设计和实现
项目使用Java swing+mysql开发,可实现基础数据维护、用户登录注册、社团信息列表查看、社团信息添加、社团信息修改、社团信息删除以及退出注销等功能、界面设计比较简单易学、适合作为Java课设设计以及学习技术使用,需要的朋友参考下吧2021-08-08
解决Eclipse配置Tomcat出现Cannot create a server using the selected
这篇文章主要介绍了解决Eclipse配置Tomcat出现Cannot create a server using the selected type错误的相关资料,需要的朋友可以参考下2017-02-02
String类型传递是值传递,char[]类型传递是引用传递的实现
下面小编就为大家带来一篇String类型传递是值传递,char[]类型传递是引用传递的实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看不2016-09-09
synchronized 和 Lock 的异同点(如何让选择)
这篇文章主要介绍了 synchronized和Lock的异同点(如何让选择),文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下2022-09-09
SpringBoot详解如果通过@Value注解给静态变量注入值
这篇文章主要介绍了springboot如何通过@Value给静态变量注入值,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-06-06


最新评论