Nuxt静态部署API跨域问题及客户端请求异常排查
问题解决思路
核心问题分析
- 跨域原因:部署后你的API请求是在客户端浏览器发起的,目标API的CORS策略不允许你部署后的域名访问,所以触发跨域错误。本地开发时API可能默认允许
localhost域名访问,或者Nuxt开发服务器自动做了CORS兼容处理,因此能正常请求。 - 静态生成未缓存数据:你的API调用是在Vuex action中,但触发时机是客户端(比如组件
mounted钩子),这种情况下Nuxt静态生成(generate)阶段不会在服务器端预取数据,导致客户端每次加载都要重新发起API请求,和你预期的“数据缓存到static目录”不符。
解决方案
方案1:静态生成时预取数据(推荐)
把API请求放到Nuxt提供的服务器端预取钩子中,这样执行yarn generate时会在服务器端请求API,将数据直接打包到静态文件里,客户端加载后直接使用,无需再发起请求,从根源解决跨域问题。
具体操作:
在你的页面组件中使用asyncData钩子调用Vuex action:
<template> <!-- 页面内容 --> </template> <script> export default { // 静态生成阶段会在服务器端执行该钩子 async asyncData({ store }) { await store.dispatch('fetchUpcomingGames') } } </script>
也可以使用页面的fetch钩子(效果类似,适合需要将数据存入Vuex的场景):
<script> export default { async fetch({ store }) { await store.dispatch('fetchUpcomingGames') } } </script>
方案2:配置代理绕过CORS(适合必须客户端请求的场景)
如果因为业务需求必须在客户端发起API请求,可以通过代理将请求转发到目标API,绕过浏览器的CORS限制。
步骤1:修改Nuxt配置
先安装@nuxtjs/proxy模块,再更新nuxt.config.js:
target: 'static', modules: [ '@nuxtjs/axios', '@nuxtjs/proxy' // 新增代理模块 ], axios: { proxy: true // 开启代理功能 }, proxy: { '/api/': { target: 'https://api.pandascore.co', pathRewrite: { '^/api/': '' } // 移除请求路径中的/api前缀 } }
步骤2:修改API请求路径
将Vuex action里的请求路径替换为代理路径:
export const actions = { async fetchUpcomingGames({ commit }) { // 用代理路径替代原外部API URL const response = await this.$axios.get('/api/matches/upcoming?sort=&page[number]=1&size=100&token=MY_TOKEN') commit('setUpcomingGames', response.data) } }
(注:原URL中page=number=1的参数格式存在错误,修正为page[number]=1更符合API规范)
步骤3:配置Netlify重写规则
在项目根目录创建netlify.toml文件,添加代理转发规则:
[[redirects]] from = "/api/*" to = "https://api.pandascore.co/:splat" status = 200
如果部署在AWS S3+CloudFront,则需要在CloudFront中配置行为转发,将/api/*路径的请求转发到目标API。
额外注意事项
- 不要在客户端代码中直接暴露API Token(比如你的
MY_TOKEN),静态部署后任何人都能看到这个Token,存在严重安全风险!建议将Token存入环境变量,在静态生成阶段(方案1)的服务器端使用,或者通过Netlify的环境变量配置代理时注入。
内容的提问来源于stack exchange,提问作者Cesar Bhering
相关产品推荐
相关产品推荐

