当前位置: 首页 > 科技观察

前后端分离后,JavaWeb开发如何解决跨域问题

时间:2023-03-20 15:08:30 科技观察

做Web开发,经常会遇到跨域问题,面试时也经常被问到朋友。这不,另一个工作了3年的小伙伴被问到这样的问题,说前后端分离后,如何解决跨域问题。今天,我就把我的理解分享给大家。很多小伙伴都单独问过我这个问题。很多小伙伴知道怎么解决跨域问题,但是不知道跨域问题是怎么产生的。因此,在回答跨域解决方案之前,我们先介绍一下跨域的原因。1、原因是一般的浏览器都有一种安全机制,叫做同源策略限制。所谓同源策略,就是用户输入的URL中包含的协议、域名、端口完全相同。也就是说,当我们使用浏览器访问网页时,必须遵守同源策略的要求才能访问。如果有一处不同,浏览器就会觉得有安全隐患,不想让你使用这个接口的数据。比如在http://localhost:8080/index页面,使用Ajax访问https://localhost:8081/index.json接口数据时,两个url的协议和端口不同,也就是不同来源,这会创建跨域访问。当然,浏览器还是会向后台服务器发送这个请求,但是浏览器不会收到服务器的响应结果。举个比较通俗的例子,就像你去肯德基点菜,硬要点一碗兰州拉面。店员虽然鄙视你,但还是会打电话问兰州拉面馆的事。商品。所以,你没有吃到兰州拉面。其中,有一个异常操作,就是虽然你点了兰州拉面,肯德基店员还是打电话给你代餐。是不供应肯德基的拉面店。来这里,就可以吃到兰州拉面了。在这种情况下,店员相当于浏览器,肯德基相当于当前浏览的网页,兰州拉面相当于后台服务的接口。肯德基和兰州拉面不是同一家店主,起源不同。拉州拉面就是你要的界面数据。但是,如果使用Postman等开发工具进行交互,则不会出现跨域问题,这是浏览器特有的局限性。其实,跨域问题不仅仅是前后端分离之后的问题。开发后端的程序员一般都遇到过跨域问题。只是前后端开发分离后,前端开发体现的跨域问题更加明显,往往需要后端开发人员来解决。2.Preflightrequest为了支持跨域访问,浏览器设置了preflight机制。也就是说,当发送跨域请求时,浏览器会自动发送一个查询请求,称为预检查请求,确认目标资源是否支持跨域。如果请求满足以下条件,浏览器将不会发送预检请求:(1)请求方法为GET、PosT.HEAD中的任意一种(2)请求头包含Accept、Accept-Language、Content-Language、Content-类型、DPR、下行链路、保存数据、Viewport.Width、宽度字段。(3)Content-Type取值为text/plain、multipart/form-data、application/x-ww-form-urlencoded中的任意一种。但是在实际项目开发中,我们请求的Content-Type一般是text/html、application/json等格式,或者使用自定义请求头会触发preflight请求。浏览器在得到preflight请求的响应结果后,判断服务器是否有权限访问这个资源,就会重新请求真实的URL,如果不允许,就会报这样的错误。已被CORS策略阻止:请求的资源上不存在“Access-control1-A11ow-Origin”标头。3.如何解决?我们可以利用浏览器的预检机制。我只需要在后端服务中添加CORS策略配置即可解决跨域问题。CORS的全称是CrossOriginResourceSharing,翻译过来就是跨域资源共享。具体解决方案有四种:1)如果是普通的Web项目,只需要在服务的根目录下添加一个crossdomain.xml文件即可。文件格式如下:当然这种方式不够灵活,在使用的情况下会存在一些安全隐患过度授权。2)如果是Spring项目,可以加一个过滤器或者拦截器来处理跨域。如代码所示:publicclassCorsFilterimplementsFilter{@OverridepublicvoiddoFilter(ServletRequestreq,ServletResponseres,FilterChainchain)throwsIOException,ServletException{HttpServletResponseresponse=(HttpServlet"Accesser-Control-Response)resset;readOrigin","*");response.setHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS,DELETE");response.setHeader("Access-Control-Max-Age","3600");response.setHeader("Access-Control-Allow-Headers","x-requested-with");chain.doFilter(req,res);}}3)如果是SpringBoot项目,只需要在方法上加上@CrossOrigin注解即可,如代码所示:@GetMapping("/list")@CrossOriginpublicListlist(){。..}如果需要支持跨域的方法比较多,可以加上Filters,比Spring更简洁,代码如下:@ConfigurationpublicclassCorsConfig{@BeanpublicCorsFiltercorsFilter(){CorsConfigurationcorsConfiguration=新的CorsConfiguration();corsConfiguration.addAllowedOrigin("*");corsConfiguration.addAllowedHeader("*");corsConfiguration.addAllowedMethod("*");UrlBasedCorsConfigurationSourcesource=newUrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**",corsConfiguration);returnnewCorsFilter(source);}}4)SpringBoot项目还有一个更方便的实现WebMvcConfigurer接口来实现跨域支持,如代码所示:"GET","POST","PUT","DELETE","HEAD","OPTIONS").allowCredentials(true)I.maxAge(3600).allowedHeaders("*");l}}只有需要重写addCorsMapping()方法,以上是解决JavaWeb跨域问题的方法。