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

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

首先网上最多的方案是用代理,例如这篇:https://blog.csdn.net/admin_web/article/details/121924527

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

不是配置问题!

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

// 允许跨域
func Options() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method
		c.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()
	}
}

报错

我后端完整的请求:http://localhost:10001/captcha

我的baseurl如下图:
在这里插入图片描述我的请求接口这么写的,"captcha"就是相对路径:

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

然后请求:
在这里插入图片描述
看报错很明显,提示就是跨域,都提示这么明显了,我没理由怀疑他吧,所以一晚上都在往这个方向尝试。

实际问题

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

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

和原来相比,就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:用chrome调试时,更改了vite配置一定要重新run ,并且强制清理缓存并硬性重新加载,不然可能看到的是假象,我都被折磨死了。

实际请求的却是端口3000,这个端口是我前端的端口。而不是后端的端口,但是我看后端,确实有请求进入的:
在这里插入图片描述
说明代理是生效的,上面请求显示3000端口应该是代理的效果了。

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

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

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

我加了个rewrite,其他不变,然后再看结果:
在这里插入图片描述
在这里插入图片描述
还是报错,但是确实发现链接上的/api给去掉了。后端其实也接收到请求了,但是被重定向了,然后就没有下文了。这也不行呀,没法正常请求。

是不是这个rewrite不好使?

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

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

在这里插入图片描述
好家伙,真的可以,加了反斜杠就能解决这个重定向的问题,也能正常使用,所以,rewrite也是有用的。

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

在这里插入图片描述
仔细看,其实还是会重定向,但是,这种情况下能够正常访问到接口。

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

总结

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

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

  • 17
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lsjweiyi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值