后端重定向导致React应用CORS跨域错误求助
跨域重定向引发的CORS错误解决方法
问题场景
在localhost:8090运行Go Gin后端服务,从localhost:3000的React应用发起请求,后端处理完成后会重定向至https://www.google.com,但触发了CORS错误。
相关代码
前端React请求代码
function processReq() { fetch(`http://localhost:8090/some-process`, { method: "GET", headers: { Accept: "application/json", } } ) .then(response => { console.log(response); }).catch(err => console.log(err)) }
后端Gin处理逻辑
r.GET("/some-process", handlers.DoProcess) func DoProcess(c *gin.Context) { // 业务处理逻辑 var w http.ResponseWriter = c.Writer http.Redirect(w, c.Request, "https://www.google.com", http.StatusSeeOther) }
已配置的CORS中间件
func CORS() gin.HandlerFunc { return func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, Accept, Origin, Cache-Control, X-Requested-With") c.Writer.Header().Set("Access-Control-Allow-Methods", "*") if c.Request.Method == "OPTIONS" { c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, Accept, Origin, Cache-Control, X-Requested-With") c.Writer.Header().Set("Access-Control-Allow-Methods", "*") c.AbortWithStatus(204) return } c.Next() } }
触发的错误信息
Access to fetch at 'https://www.google.com/' (redirected from 'http://localhost:8090/some-process') from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
错误原因
浏览器会自动跟随后端的重定向请求,向https://www.google.com发起请求,但谷歌的服务器不会为localhost:3000添加Access-Control-Allow-Origin响应头,导致跨域校验失败——你的CORS中间件只作用于自己的后端服务,无法控制第三方服务器的响应头。
解决方案
方案1:后端返回重定向地址,前端跳转(推荐)
修改后端处理函数,不直接执行HTTP重定向,而是返回目标URL,让前端通过页面跳转的方式完成:
func DoProcess(c *gin.Context) { // 完成业务处理 c.JSON(http.StatusOK, gin.H{ "redirect_url": "https://www.google.com", }) }
更新前端代码,拿到返回的URL后直接跳转:
function processReq() { fetch(`http://localhost:8090/some-process`, { method: "GET", headers: { Accept: "application/json", } } ) .then(response => response.json()) .then(data => { window.location.href = data.redirect_url; }).catch(err => console.log(err)) }
页面跳转不属于AJAX请求范畴,不受CORS规则限制,彻底解决问题。
方案2:使用no-cors模式(仅适用于无需响应内容的场景)
如果必须保留后端重定向逻辑,可以修改前端fetch请求,添加mode: 'no-cors':
function processReq() { fetch(`http://localhost:8090/some-process`, { method: "GET", mode: 'no-cors', headers: { Accept: "application/json", } } ) .then(response => { console.log(response); }).catch(err => console.log(err)) }
但这种模式下,浏览器会返回不透明响应,你无法读取响应内容或状态码,仅适用于不需要处理返回数据的场景,因此不推荐作为常规解决方案。
内容的提问来源于stack exchange,提问作者Olalekan
相关产品推荐
相关产品推荐

