背景
今天在开发vite+vue项目的时候,遇到一个非常棘手的问题。
在项目登录的界面,通过get获取验证码是ok的,但是通过post调用登录接口报403。
此时,已经使用vite做了代理,但是后端并未收到请求,所以403只能是前端报的,而不是后端返回的。
分析
1、根据AI的提示,检查Content-Type是否有问题。
没有问题,设置的是'Content-Type': 'application/json;charset=utf-8',
,即便请求的内容加密成字符串了,当设置这个请求头后,后端在解密字符串后,就会成为json格式的请求。
2、跨域问题
虽然提示Invalid CORS request
,但是没有很明显的项目中遇到的跨域提示,而且设置了vite代理,应该不存在跨域问题。
是不是代理方式写的不对?经过AI检查,没有问题。
3、服务器端限制
不可能,服务未到达服务器。
4、网络问题?
比如断网?那也不会,验证码都可以请求到。
5、如果前端data错误或者header错误,会有403错误吗?
AI:在请求到达后端的情况下,前端 data 或 headers 的错误确实可能引发 403 Forbidden 错误,但具体取决于后端的逻辑。如果请求根本没有到达后端,问题一般不会是 data 或 headers,而是跨域配置、网络问题、或者请求本身的阻止。
6、通过curl -X POST -H 'Content-Type: application/json' -d 'xxx...' http://10.8.3.48:8082/login
的方式却可以到达后端,但是vite代理不能到达,难道vite拦截了?
通过加入vite的打印信息,可以看到确实没有成功:
server: {
proxy: {
[env.VITE_BASE_API]: {
target: env.VITE_PROXY_URL,
changeOrigin: true,
rewrite: path => path.replace(new RegExp(`^${env.VITE_BASE_API}`), ''),
configure: (proxy, options) => {
// 添加代理事件监听器,用于调试
proxy.on('proxyReq', (proxyReq, req, res) => {
console.log('Proxy Request:', {
url: req.url,
headers: proxyReq.getHeaders()
});
});
proxy.on('proxyRes', (proxyRes, req, res) => {
console.log('Proxy Response:', {
statusCode: proxyRes.statusCode,
headers: proxyRes.headers
});
});
}
}
}
}
那就很奇怪了。
AI说,可能是因为baseURL 带了具体的域名,那么就不会走vite代理了吗?必须是一个相对地址吗?
是的,如果 baseURL
带了具体的域名(例如 'http://localhost:5173/dev-api'
),请求不会走 Vite 的代理。这是因为 Vite 的代理配置 (server.proxy
) 只对相对路径(例如 /api
或 /dev-api
)生效。如果请求中带有完整的 URL(即包含协议和域名),浏览器会直接发起请求到该域名,而不会通过本地开发服务器的代理。
所以,需要修改domain.js代码:
const nodeEnv = import.meta.env.VITE_APP_NODE_ENV || 'development'
const target = import.meta.env.VITE_PROXY_URL
const getBaseURL = () => {
// 本地开发环境
if (nodeEnv === 'development') {
// return `${location.origin}${import.meta.env.VITE_BASE_API}`
// 修改为
// 只返回 base api 路径,让代理服务器处理
return import.meta.env.VITE_BASE_API
}
// 线上生产环境
return target
}
export const baseURL = getBaseURL()
修改后,依然报403错误。
没办法了,最后在google搜索得到答案。
解决
解决方案:在vite代理的请求中,移除请求头referer和origin。
server: {
open: false,
host: '0.0.0.0',
proxy: {
[env.VITE_BASE_API]: {
target: env.VITE_PROXY_URL,
changeOrigin: true,
rewrite: path => path.replace(new RegExp(`^${env.VITE_BASE_API}`), ''),
configure: (proxy, options) => {
// 添加代理事件监听器,用于调试
proxy.on('proxyReq', (proxyReq, req, res) => {
proxyReq.removeHeader('referer') // 移除请求头
proxyReq.removeHeader('origin') // 移除请求头
})
},
},
},
},
原因:在使用 Vite 的代理时,POST 请求返回 403 通常是由于代理或目标服务器对 Referer 和 Origin 字段的校验引发的。代理服务器可能会因为这两个字段不符合预期而拦截请求,而非直接转发给目标服务器。移除这两个字段可以绕过代理或目标服务器的来源校验,从而使请求成功。
然而,有些项目未移除这些字段也能成功,可能是因为代理配置(如 changeOrigin: true)自动伪装了请求来源,或目标服务器对来源字段校验宽松。
参考地址:https://blog.csdn.net/m0_73334325/article/details/131254774