详解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.后端服务放开跨域请求
其中,以最后两种见常。
详细方案
本文主要描述第四种解决方案:后端服务放开跨域请求。
springboot中放开跨域请求很简单。
1.增加一个configuration类
importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importorg.springframework.web.cors.CorsConfiguration; importorg.springframework.web.cors.UrlBasedCorsConfigurationSource; importorg.springframework.web.filter.CorsFilter; /** *跨域访问配置 *@authorwencst *@creation2017年8月18日 */ @Configuration publicclassCustomCORSConfiguration{ privateCorsConfigurationbuildConfig(){ CorsConfigurationcorsConfiguration=newCorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); returncorsConfiguration; } @Bean publicCorsFiltercorsFilter(){ UrlBasedCorsConfigurationSourcesource=newUrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**",buildConfig()); returnnewCorsFilter(source); } }
增加此类以后,非同源http访问可以正常进行了,但是会不会有什么问题呢?
对于大部分网站依然需要使用cookie作为前后端传输数据的媒介,然而默认非同源请求是不携带cookie信息的。
2.服务端允许跨域携带cookie信息
在springboot2.0.2中,允许跨域设置比较简单,只需增加一个configuration类即可。
importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importorg.springframework.web.cors.CorsConfiguration; importorg.springframework.web.cors.UrlBasedCorsConfigurationSource; importorg.springframework.web.filter.CorsFilter; /** *跨域访问配置 *@authorwencst *@creation2017年8月18日 */ @Configuration publicclassCustomCORSConfiguration{ privateCorsConfigurationbuildConfig(){ CorsConfigurationcorsConfiguration=newCorsConfiguration(); 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); returncorsConfiguration; } @Bean publicCorsFiltercorsFilter(){ UrlBasedCorsConfigurationSourcesource=newUrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**",buildConfig()); returnnewCorsFilter(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); varres=eval(respon); }, error:function(){ alert('服务器发生错误!'); } });
此时,当前端向后端服务做跨域请求时,增加
xhrFields:{ withCredentials:true },
就会带上cookie信息了,同理会带上token/sessionID等等内容。
测试方法
springboot中增加一个controller
@Controller publicclassLoginController{ @RequestMapping(value="setString") @ResponseBody publicStringsetString(HttpServletRequestrequest,HttpServletResponseresponse,@RequestParamStringvalue){ request.getSession().setAttribute("username",value); return"OK"; } @RequestMapping(value="getString") @ResponseBody publicStringgetString(HttpServletRequestrequest,HttpServletResponseresponse){ Stringusername=(String)request.getSession().getAttribute("username"); returnusername; } }
增加一个index.html,来访问跨域访问。
跨域请求 set
get
html文件可以单独本地访问即可出现效果,并不一定要形成服务访问。
当服务端不允许跨域访问时,html文件访问均报错,并调用失败。
当服务端允许跨域访问时,html请求访问成功。
当服务端开启cookie传递,并在html文件中增加xhrFields参数时,session生效。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。