首页 >> 大全

神坑——后端允许了跨域但是前端(vue3+vite+axios)仍然提示跨域

2023-09-08 大全 26 作者:考证青年

这个问题坑了我整整一个晚上。·这明明是个非常常见的问题,我自己也遇到好多次了,以前都是后端允许跨域就可以了。但是这次就是不行!

首先网上最多的方案是用代理,例如这篇:

我一晚上也主要在按照这些方法去尝试,但是我努力一个晚上,都不行,一直怀疑是自己的姿势不对!最后在快要放弃前(12点多,不清醒了),瞎猫碰上死耗子,居然解决了。

不是配置问题!

PS:我的后端用go写的,这里也贴一下我的允许跨域方案:

// 允许跨域
func Options() gin.HandlerFunc {return func(c *gin.Context) {method := c.Request.Methodc.Header("Access-Control-Allow-Origin", "*")c.Header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers,Authorization,User-Agent, Keep-Alive, Content-Type, X-Requested-With,X-CSRF-Token,AccessToken,Token")c.Header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, OPTIONS")c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")c.Header("Access-Control-Allow-Credentials", "true")// 放行所有OPTIONS方法if method == "OPTIONS" {c.AbortWithStatus(http.StatusAccepted)}c.Next()}
}

报错

我后端完整的请求::10001/

我的如下图:

我的请求接口这么写的,""就是相对路径:

export function getcaptchaId() {return get<{ id: string }>("captcha");
}

然后请求:

看报错很明显,提示就是跨域,都提示这么明显了,我没理由怀疑他吧,所以一晚上都在往这个方向尝试。

实际问题

然而真实答案是因为少了个/,其他不变,就改动下面一个地方:

export function getcaptchaId() {return get<{ id: string }>("captcha/");
}

和原来相比,就后面加了个/。然后,就解决了!对,就是这么的简单。

原理分析

于是我就去查了下这个/的作用,这篇文章有讲解,它里面提到有重定向,于是我去掉反斜杠再去试试,然后我再看看我的后端:

[GIN-debug] redirecting request 301: /captcha/ --> /captcha/

后端确实是有提示访问进来被重定向了。但是,依然没用,前端还是提示跨域。

所以,可能原因是:go的后端虽然能够像文章分析的那样重定向,但是,重定向之后,并不会再经过允许跨域的中间件(因为我的print没有打印出来,说明都没进入),所以,这里可以认为后端配置的允许跨域中间件并没有生效。

使用代理存在的问题

网上普遍提示使用代理去解决。我尝试了一晚上不成功(昨晚有点迷糊了,没有找到本质的原因,一直不成功,下面的测试是我第二天写这篇博客才测试的),不甘心,要分析下它的问题。

下面先假设我还没加那个/,存在跨域问题的请情况下去使用代理。

我使用vite的代理:

    //反向代理配置 - 可解决跨域问题server: {proxy: {"/api": {target: "http://localhost:10001/",changeOrigin: true},},},

然后:

axios.defaults.baseURL = "/api"; // 设置服务端地址

然后看报错:

PS:用调试时,更改了vite配置一定要重新run ,并且强制清理缓存并硬性重新加载,不然可能看到的是假象,我都被折磨死了。

实际请求的却是端口3000,这个端口是我前端的端口。而不是后端的端口,但是我看后端,确实有请求进入的:

说明代理是生效的,上面请求显示3000端口应该是代理的效果了。

这里的问题是,我的请求并没有/api,所以请求不到。

然后我发现还有个方法,我再改了一下:

    //反向代理配置 - 可解决跨域问题server: {proxy: {"/api": {target: "http://localhost:10001/",changeOrigin: true,rewrite: (path) => path.replace("/api", ""),},},},

我加了个,其他不变,然后再看结果:

还是报错,但是确实发现链接上的/api给去掉了。后端其实也接收到请求了,但是被重定向了,然后就没有下文了。这也不行呀,没法正常请求。

是不是这个不好使?

上面的原理分析不是说了这个重定向的问题吗,所以我还想试一下,加上那个/:

export function getcaptchaId() {return get<{ id: string }>("captcha/"); // 加上反斜杠
}

好家伙,真的可以,加了反斜杠就能解决这个重定向的问题,也能正常使用,所以,也是有用的。

当然,也可以不使用,在我后端路径上加个/api,然后后面不加反斜杠, 试试看吧:

仔细看,其实还是会重定向,但是,这种情况下能够正常访问到接口。

到这里,说明这个代理的方法确实也能解决跨域问题。

总结 实际上后端允许跨域之后,前端就不存在跨域问题,是我的姿势不对,请求的链接最后没有加/,但是浏览器这个错误提示很误导人。代理的方式也能解决跨域的问题,这种情况下,后端就不需要配置允许跨域了。vite代理的有点小毛病,虽然能够发挥作用,但是也要注意链接最后要加上/,否则请求会失败

这么一个傻逼问题,真的折磨人呀!这通下来,以后应该不会被跨域问题折磨了吧。。。。。。。

关于我们

最火推荐

小编推荐

联系我们


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