首页 >> 大全

前后端分离 跨域问题(针对SpringBoot项目和GateWay跨域)

2023-09-13 大全 32 作者:考证青年

后端分离 跨域问题(针对项目和跨域) 问题描述 :

进行JWT认证登录时,前端的地址为:8080 , 登录时发送登录请求:99/api/blog/admin/login,此时存在跨域问题,我们对该问题进行了长时间的解决,以下是我们解决问题的方法

前端解决

前端我们主要使用代理的方式进行解决,我们在与babel..js同级的目录下创建一个vue..js文件,然后在其中使用设置代理

注意 : 我们虽然设置了代理,但是页面中查看请求路径仍然是:8080/api/blog/admin/login但是调试过程中post请求会报400错误 ! ! !

这里存在一个坑,我们在发送post请求的时候,必须将请求的数据进行序列化处理! ! ! !

axios发送请求参数默认是json格式,后端识别不了

下面使用导入的qs包对data数据进行序列化处理…

npm i qs --save

//main.js
import axios from 'axios'//post请求返回400  ----> 对post请求的数据进行序列化
import qs from 'qs'
axios.interceptors.request.use(config => {if (config.type == 'formData' || config.method != 'post') {return config}config.data = qs.stringify(config.data)return config
}, (err) => {return Promise.reject(err);
})

//vue.config.js自己创建
module.exports = {devServer: { // 设置代理hot: true, //热加载// host: '127.0.0.0', //ip地址port: 8080, //端口(前端的端口)https: false, //false关闭https,true为开启open: true, //自动打开浏览器proxy: {'/api': { //本地 (凡是遇到/api开头的请求,就在请求前添加上target目标接口)target: 'http://localhost:99/',changeOrigin: true,// pathRewrite: {//     "^/api": "" //用'/api' 代替 'http://localhost:99/api'// }}}}
}

//请求页面
const res = await this.$http.post('/api/blog/admin/login/', this.form)

请求地址::99/api/blog/admin/login/

前端地址::8080

备注(设置基准请求地址):

axios.. = “:99/api”

//在请求拦截设置Authorization
config.headers.Authorization  =  window.sessionStorage.getItem('token')

后端解决: 方式1 : 在类上添加 @注解

@CrossOrigin
@RestController
@RequestMapping("/admin")
public class UserController {
...
}//这里我们针对的是SpringBoot项目,如果是SpringCloud项目建议统一去网关中进行下面方法的配置

方式2 : 在中添加一个过滤器,针对vue-

/*** Created by FengBin on 2021/5/7 21:07* 过滤器*/
@Component //注意添加@Component注解,将注入到Spring容器中去
public class SimpleFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) res;response.setHeader("Access-Control-Allow-Origin", "*"); //"*"表示所有请求都允许跨域response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD"); //设置允许跨域的方法response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "access-control-allow-origin, authority, content-type, version-info, X-Requested-With");chain.doFilter(req, res);}@Overridepublic void destroy() {}
}

方式3 : 注册一个过滤器,针对vue-

jq跨域问题怎么解决_

package com.feng.blog.config;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;@Configuration
public class CorsConfig {@Beanpublic CorsFilter corsWebFilter() {CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.addAllowedOriginPattern("*");corsConfiguration.addAllowedHeader("*");corsConfiguration.addAllowedMethod("*");corsConfiguration.setAllowCredentials(true);UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();urlBasedCorsConfigurationSource.registerCorsConfiguration("/**",corsConfiguration);return new CorsFilter(urlBasedCorsConfigurationSource);}
}

方式4 : 利用反向代理解决跨域问题

参考nginx配置文档

方式5 : 在进行配置

如果我们是使用架构,很多请求都需要跨域访问,我们可以在的网关的.xml文件中进行集中配置,因为我们的网关中已经集成了过滤器

 spring:cloud:gateway:globalcors:cors-configurations:'[/**]':allowedOrigins: "http://localhost:8080"allowMethods:- GET- POST- OPTIONS- DELETE- HEAD- PUT- PATCH

新的坑 问题描述 :

虽然我们按照上面的前端和后端配置,使得普通的跨域访问问题得到了解决,但是,出现了下面新的问题…

即我们只要配置了请求头信息,再想后端发起请求访问的时候,仍然报403跨域问题,不携带请求头信息,则没有跨域问题,具体问题见下面内容

1. 不设置时向后端发送请求,返回500,服务器能收到我的请求,但是需要我携带token

2. 设置请求头,就返回403跨域问题,后端都不能接受我的请求

3. 后端已经设置了允许跨域,并且已经默认所有请求能通过了,还是有问题

刚开始的时候,我们尝试了很多方法,这个问题还没有得到解决,只要请求在请求头里携带token参数,发送请求就会出现的跨域访问错误,等待该问题的解决…

故我们只能被动的采取另一种方法间接解决:

将后端返回的token信息保存在请求参数中,每一次从域中获取参数的形式获取对应的值,而不是设置在请求头的中,使得这个登录携带token参数的问题得到了间接的解决

新的坑的解决方案----终极解决

在我们后面开发中,一直都会出现需要设置请求头的场景,使得我们必须解决此时携带请求头参数导致的403问题

jq跨域问题怎么解决_

从头梳理我们的跨域问题 :

首先前端的请求会到我们的网关服务,由我们的网关分发给我们对应的服务,而之前我们将跨域问题的配置设置在单独的博客微服务中,虽然它在登录的时候起到了允许跨域的作用,但是在修改请求头时,还是存在问题.

故我们尝试将配置跨域的设置,更改到了网关中

在网关的com.tfblog.gateway路径下创建config包,并在其下创建TFBlogCorsConfiguration@Configuration
public class TFBlogCorsConfiguration {@Beanpublic CorsWebFilter corsWebFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration corsConfiguration = new CorsConfiguration();//配置跨域属性corsConfiguration.addAllowedHeader("*");corsConfiguration.addAllowedMethod("*");corsConfiguration.addAllowedOrigin("*");corsConfiguration.setAllowCredentials(true);source.registerCorsConfiguration("/**",corsConfiguration);return new CorsWebFilter(source);}
}

此时我们依旧设置在前端请求中设置了请求头信息,我们发现我们的报错信息发生了变化 :

前端部分代码 :

import axios from 'axios'
axios.defaults.baseURL = "http://localhost:99/api"
import qs from 'qs'axios.interceptors.request.use(config => {//使用qs工具对data数据进行序列化处理,然后进行请求的发送处理config.data = qs.stringify(config.data)config.headers.Authorization = window.sessionStorage.getItem('token')config.headers['Cache-Control'] = 'no-cache'return config
}, (err) => {return Promise.reject(err);
})

报错信息:

to at ‘:99/api/blog/admin/login’ from ‘:8080’ has been by CORS : The ‘--Allow-’ ‘:8080,*’, but only one is .

思考 :

报错信息说我设置了相同的请求头,设置了多次,但是我根本就没有使用nginx,也没有在其他地方进行跨域的配置,只是在网关中设置了一次

探讨 :

网上的资料说大多数是nginx的同样配置跨域信息,或者 重复设置的情况,但是我们没有进行nginx的配置,故第一种情况我们排除,这里问题来了 : 是否在和vue本身就存在一层默认配置的 的情况

故我们进行的相关底层实现的查询,终于发现: 使用了,而不是,而在中进行跨域的一些配置,故我们需要先关闭中的cors,再从中中进行跨域的设置就可以解决上面出现的问题了

针对性检索的官方文档2.1.x

Important
Spring Cloud Gateway is built upon Spring Boot 2.x, Spring WebFlux, and Project Reactor. As a consequence many of the familiar synchronous libraries (Spring Data and Spring Security, for example) and patterns you may not apply when using Spring Cloud Gateway. If you are unfamiliar with these projects we suggest you begin by reading their documentation to familiarize yourself with some of the new concepts before working with Spring Cloud Gateway.
Important
Spring Cloud Gateway requires the Netty runtime provided by Spring Boot and Spring Webflux. It does not work in a traditional Servlet Container or built as a WAR.Route Predicate Factories
Spring Cloud Gateway matches routes as part of the Spring WebFlux HandlerMapping infrastructure. Spring Cloud Gateway includes many built-in Route Predicate Factories. All of these predicates match on different attributes of the HTTP request. Multiple Route Predicate Factories can be combined and are combined via logical and.

解决 :

故我们只要在网关的.yml中进行配置,关闭的cors即可

This will remove duplicate values of Access-Control-Allow-Credentials and Access-Control-Allow-Origin response headers in cases when both the gateway CORS logic and the downstream add them.

故我直接在对应服务路由的fiter下编写以下配置,完美解决了由于前端配置请求头参数而导致的跨域问题

          filters:- RewritePath=/api/blog/(?<segment>/?.*),/$\{segment}- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin Access-Control-Allow-Headers

此时完美运行,终于这个大坑解决了!!!

注意 : 这里的解决方案,参考了一位博主的解决方案,博客地址 :

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了