NuxtJS/VueJS用axios请求GitHub资源触发CORS拦截该如何解决?
报错根本原因
你遇到的CORS报错是GitHub静态资源访问策略与浏览器同源规则冲突导致的:浏览器地址栏直接访问不属于异步跨域请求,所以可以正常跟随302跳转拿到数据;而前端axios发起的异步请求受跨域规则限制,且GitHub返回的Access-Control-Allow-Origin头存在多值冲突,因此直接请求会被浏览器拦截。
之前的方案不生效的核心原因是没有处理代理转发后返回的重复跨域头,仅配置基础代理无法解决多值冲突问题。
可落地解决方案
1. 本地开发阶段:配置带头处理的Nuxt代理
如果是Nuxt2项目,先安装@nuxtjs/proxy依赖,再修改nuxt.config.js配置:
// nuxt.config.js export default { modules: ['@nuxtjs/proxy'], proxy: { '/github-proxy/': { target: 'https://github.com/', pathRewrite: { '^/github-proxy/': '' }, changeOrigin: true, // 核心配置:处理重复的跨域头 onProxyRes: (proxyRes) => { const originHeader = proxyRes.headers['access-control-allow-origin'] if (Array.isArray(originHeader)) { proxyRes.headers['access-control-allow-origin'] = originHeader[0] } proxyRes.headers['access-control-allow-credentials'] = 'true' } } } }
请求时把用户输入的GitHub链接前缀https://github.com/替换为/github-proxy/即可正常发起请求。
如果是Nuxt3项目,可直接在nuxt.config.ts中配置路由规则:
// nuxt.config.ts export default defineNuxtConfig({ devProxy: { '/github-proxy': { target: 'https://github.com', changeOrigin: true, pathRewrite: { '^/github-proxy': '' }, onProxyRes: (proxyRes) => { const originHeader = proxyRes.headers['access-control-allow-origin'] if (Array.isArray(originHeader)) { proxyRes.headers['access-control-allow-origin'] = originHeader[0] } } } } })
2. 生产环境:使用Nuxt服务端接口代理
前端代理仅在本地开发生效,生产环境建议用Nuxt自带的服务端能力转发请求,服务端请求不受跨域限制,还能自动跟随302跳转,同时可以拿到重定向后的最终地址。
以Nuxt3为例,新建server/api/github-proxy.get.ts文件:
export default defineEventHandler(async (event) => { const { url } = getQuery(event) // 自动跟随302跳转 const res = await fetch(url as string, { redirect: 'follow' }) const rawData = await res.text() return { data: rawData, status: res.status, isRedirected: res.redirected, finalUrl: res.url } })
3. 适配后的Vuex Action代码
export const actions = { async obtainURLData ({ commit }, inputURL) { try { // 调用自身服务端代理接口,完全规避跨域问题 const response = await axios.get('/api/github-proxy', { params: { url: inputURL } }) console.log('请求响应', response) console.log('原始资源数据', response.data.data) console.log('是否发生重定向', response.data.isRedirected) console.log('最终资源地址', response.data.finalUrl) if (response.data.status === 200) { // 此处补充业务逻辑 } } catch (error) { console.log('请求报错', error) if (error.response) { console.log('错误状态码', error.response.status) console.log('错误详情', error.response.data) } } } }
临时测试方案
如果只是临时测试,可以在用户输入的GitHub链接前拼接公共CORS代理前缀,不过公共代理稳定性较低,不建议在生产环境使用。
内容的提问来源于stack exchange,提问作者BATMAN_2008
相关产品推荐
相关产品推荐

