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

前后端项目分离时如何解决跨域问题?

时间:2023-03-17 18:46:34 科技观察

跨域问题是前后端分离项目中非常普遍的问题。比如codingmore学习网站前端服务运行在8080端口,后端服务运行在9002端口,那么前端服务运行在9002端口,请求后端接口会出现跨域问题.403Forbidden是HTTP协议中的一种状态码(StatusCode),表示虽然后端服务成功解析请求,但前端无权访问该资源。那么如何解决这个问题呢?通常有两种思路:在前端使用Nodejs代理(开发环境可以在生产环境使用Nginx代替)或者在后端开启跨域资源共享1.关于跨域和跨域domaindevelopers对我来说,就像是狗皮贴,不管是面试还是开发,都会经常遇到。跨域问题的原因是因为浏览器的同源策略。为了隔离潜在的恶意文件,防止不正当攻击,浏览器会限制从同一来源加载文档或脚本以及从其他来源加载资源。互动。前面我们提到,前端运行在8080端口下,后端运行在9002端口下,这种情况属于不同来源(不同域名,不同协议,不同端口),所以前端请求下8080端口直接访问9002端口,后端接口down时访问失败。正确的打开方式是什么?前面我们也提到了前端使用Nodejs代理或者后端开启跨域资源共享。让我们一一练习吧。2、Nodejs代理在Nodejs出现之前,用JavaScript编写的程序通常需要在用户的浏览器上执行。Node.js出现后,JavaScript也可以用于服务器端编程。Nodejs内置的一系列模块使得程序可以作为一个独立的服务器执行,无需IIS、Apache等Web服务。我们使用Nodejs解决跨域问题的思路是在本地创建一个虚拟服务器,代理8080端口下的前端请求,同时在9002端口下接收服务器端的响应,这样服务器与服务器之间的数据交互简单。不会有跨域问题。第一步是配置Nodejs代理服务module.exports={dev:{//PathsassetsSubDirectory:'static',assetsPublicPath:'/',proxyTable:{'/api':{target:'http://localhost:9002',//你请求的第三方接口changeOrigin:false,//会在本地创建一个虚拟服务器,然后同时发送和接收请求的数据,这样服务器之间的数据交互而且服务器也不难。会有跨域问题pathRewrite:{//路径重写,'^/api':''//替换target中的请求地址,也就是说你请求的是http://api.codingmore.top/v2/以后的XXXXX地址可以直接写成/api。}},},}第二步配置前端访问请求路径module.exports=merge(prodEnv,{NODE_ENV:'"development"',VUE_APP_BASE_API:'"/api"'//VUE_APP_BASE_API:'"http://localhost:9002"'})第三步,重启前端服务,再次点击“登录”按钮,可以看到请求的URL已经改变。以前是http://localhost:9002/users/login,现在是http://localhost:9002/users/login/localhost:8080/api/users/login。同时可以看到多了一个RemoteAddress,端口也是8080。也就是说,通过Nodejs的代理,前后端的交互是同源下的,这样不会出现跨域问题。同时可以看到服务器返回的状态码变成了200,表示请求成功。3、启用跨域资源共享跨域资源共享,也称为Cross-OriginResourceSharing,简称CORS,是一种基于HTTP头信息的机制,通过让服务器识别资源来实现跨域资源除了本身访问。第一步是启用CORS支持。在SpringBoot应用中,添加CORS支持实在是太简单了,不忍直视。只需添加一个配置类。@ConfigurationpublicclassGlobalCorsConfig{@BeanpublicCorsFiltercorsFilter(){CorsConfigurationconfig=newCorsConfiguration();//设置要允许的网站域名config.addAllowedOrigin("http://localhost:8080");//允许跨域发送cookieconfig.setAllowCredentials(true);//允许所有原始头信息config.addAllowedHeader("*");//允许所有请求方法跨域调用config.addAllowedMethod("*");UrlBasedCorsConfigurationSourcesource=newUrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**",配置);返回新的CorsFilter(来源);}}第二步,重启后台服务,再次点击登录按钮,发现请求可以正常访问了。本例中,如果后台返回Access-Control-Allow-Origin:http://localhost:8080,则表示后台运行在9002端口的接口可以被8080端口的前端请求访问到。如果所有的域名都是允许跨域调用,只需要改一行代码。//允许所有域名跨域调用config.addAllowedOriginPattern("*");//设置你要允许的网站域名//config.addAllowedOrigin("http://localhost:8080");对于登录这种简单的请求而言,不会触发CORS预检,所以不需要在服务端添加其他配置。那么什么是简单请求呢?1)请求方式为以下三种方式之一:HEADGETPOST2)HTTP头信息不超过以下字段:AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type:限于三个值application/x-www-form-urlencoded,multipart/form-data,text/plain对于会触发CORSpreflight的非简单请求(例如请求方式为PUT或DELETE,或者Content-Type字段的类型为application/json,或者请求头包含一些自定义字段),我该怎么办?在非简单请求正式通信之前,会添加一个HTTP查询请求,称为“预检”请求。预检请求通过后,返回正常的响应内容。以Codingmall的文章管理页面为例。该页面将向后端发起posts/queryPageable分页查询。请求中包含自定义的消息头Authorization,所以浏览器会认为该请求是一个非简单请求,然后会自动发起一个OPTIONS请求,但是由于我们的SpringBoot项目集成了SpringsScurity安全管理框架,所以登录鉴权是OPTIONS请求没有释放,导致校验失败,没有返回文章分页请求的响应数据。第三步,通过如下代码传递OPTIONS请求。公共类SecurityConfig扩展WebSecurityConfigurerAdapter{@Overrideprotectedvoidconfigure(HttpSecurityhttpSecurity)throwsException{//允许跨域请求的OPTIONS请求registry.antMatchers(HttpMethod.OPTIONS)。允许全部();}}再次重启后端服务,重新访问文章列表界面,发现有响应数据。非简单请求必须先使用OPTIONS请求方式向服务器发起preflight请求,以了解服务器是否允许实际请求。“预检请求”的使用避免了跨域请求对服务器上用户数据的意外影响。下面通过两张图来简单总结一下预检请求的全过程。第一个是发起OPTIONS预检请求:第二章是发起正式请求:4.源码路径编程cat后端源码:https://github。com/itwanger/coding-more编程猫后台管理前端源码:https://github.com/itwanger/codingmore-admin-web参考链接:跨域:https://segmentfault.com/a/1190000015597029CORS:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS阮一峰:https://www.ruanyifeng.com/blog/2016/04/cors.html简单请求+预检请求:https://github.com/amandakelake/blog/issues/62