经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring Boot » 查看文章
详解Spring Boot 2.0.2+Ajax解决跨域请求的问题
来源:jb51  时间:2019/3/6 8:57:40  对本文有异议

问题描述

后端域名为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类

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.cors.CorsConfiguration;
  4. import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
  5. import org.springframework.web.filter.CorsFilter;
  6.  
  7. /**
  8. * 跨域访问配置
  9. * @author wencst
  10. * @creation 2017年8月18日
  11. */
  12. @Configuration
  13. public class CustomCORSConfiguration {
  14. private CorsConfiguration buildConfig() {
  15. CorsConfiguration corsConfiguration = new CorsConfiguration();
  16. corsConfiguration.addAllowedOrigin("*");
  17. corsConfiguration.addAllowedHeader("*");
  18. corsConfiguration.addAllowedMethod("*");
  19. return corsConfiguration;
  20. }
  21. @Bean
  22. public CorsFilter corsFilter() {
  23. UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  24. source.registerCorsConfiguration("/**", buildConfig());
  25. return new CorsFilter(source);
  26. }
  27. }
  28.  

增加此类以后,非同源http访问可以正常进行了,但是会不会有什么问题呢?

对于大部分网站依然需要使用cookie作为前后端传输数据的媒介,然而默认非同源请求是不携带cookie信息的。

2.服务端允许跨域携带cookie信息

在spring boot2.0.2中,允许跨域设置比较简单,只需增加一个configuration类即可。

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.cors.CorsConfiguration;
  4. import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
  5. import org.springframework.web.filter.CorsFilter;
  6.  
  7. /**
  8. * 跨域访问配置
  9. * @author wencst
  10. * @creation 2017年8月18日
  11. */
  12. @Configuration
  13. public class CustomCORSConfiguration {
  14. private CorsConfiguration buildConfig() {
  15. CorsConfiguration corsConfiguration = new CorsConfiguration();
  16. corsConfiguration.addAllowedOrigin("*");
  17. corsConfiguration.addAllowedHeader("*");
  18. corsConfiguration.addAllowedMethod("*");
  19. corsConfiguration.addExposedHeader("Content-Type");
  20. corsConfiguration.addExposedHeader( "X-Requested-With");
  21. corsConfiguration.addExposedHeader("accept");
  22. corsConfiguration.addExposedHeader("Origin");
  23. corsConfiguration.addExposedHeader( "Access-Control-Request-Method");
  24. corsConfiguration.addExposedHeader("Access-Control-Request-Headers");
  25. corsConfiguration.setAllowCredentials(true);
  26. return corsConfiguration;
  27. }
  28. @Bean
  29. public CorsFilter corsFilter() {
  30. UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  31. source.registerCorsConfiguration("/**", buildConfig());
  32. return new CorsFilter(source);
  33. }
  34. }
  35.  

增加信息后,在前端依然需要调整AJAX请求,才能在非同源请求中携带cookie信息。

3.前端调整

  1. $.ajax({
  2. url: 'http://beta.roboming.com/api.php?s=/Public/AdminLogin.html',
  3. type: 'POST',
  4. async:true,
  5. xhrFields:{
  6. withCredentials:true
  7. },
  8. data: {
  9. username:userName,
  10. password:pwd
  11. },
  12. success: function(respon){
  13. console.log(respon);
  14. var res=eval(respon);
  15. },
  16. error: function(){
  17. alert('服务器发生错误!');
  18. }
  19. });

此时,当前端向后端服务做跨域请求时,增加

  1. xhrFields:{
  2. withCredentials:true
  3. },

就会带上cookie信息了,同理会带上token/sessionID等等内容。

测试方法

spring boot中增加一个controller

  1. @Controller
  2. public class LoginController {
  3. @RequestMapping(value = "setString")
  4. @ResponseBody
  5. public String setString(HttpServletRequest request, HttpServletResponse response@RequestParam String value) {
  6. request.getSession().setAttribute("username", value);
  7. return "OK";
  8. }
  9. @RequestMapping(value = "getString")
  10. @ResponseBody
  11. public String getString(HttpServletRequest request, HttpServletResponse response) {
  12. String username = (String)request.getSession().getAttribute("username");
  13. return username;
  14. }
  15. }

增加一个index.html,来访问跨域访问。

  1. <html>
  2. <head>
  3. <meta charset="utf-8">
  4. <title>跨域请求</title>
  5. <script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
  6. </head>
  7. <body>
  8. <button onclick="set()">set</button>
  9. <br><br>
  10. <button onclick="get()">get</button>
  11. <script>
  12. function set(){
  13. $.ajax({
  14. url:'http://wencst.vicp.net/setString?value=10',
  15. xhrFields:{
  16. withCredentials:true
  17. },
  18. success:function(result){
  19. alert(result);
  20. }
  21. });
  22. }
  23. function get(){
  24. $.ajax({
  25. url:'http://wencst.vicp.net/getString',
  26. xhrFields:{
  27. withCredentials:true
  28. },
  29. success:function(result){
  30. alert(result);
  31. }
  32. });
  33. }
  34. </script>
  35. </body>
  36. </html>

html文件可以单独本地访问即可出现效果,并不一定要形成服务访问。

当服务端不允许跨域访问时,html文件访问均报错,并调用失败。

当服务端允许跨域访问时,html请求访问成功。

当服务端开启cookie传递,并在html文件中增加 xhrFields参数时,session生效

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号