You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt3 SSR页面useFetch代理失效问题求助及原因排查

问题分析与解决

问题原因

Nuxt3 的 devProxy 仅对客户端浏览器发起的请求生效。而 SSR 渲染阶段,useFetch 是在 Node.js 服务端环境直接发起请求的:

  • 当你使用相对路径 /api/product/getProductById 时,服务端会把它当成 Nuxt 自身的路由路径去匹配,而非触发代理转发,因此 Vue Router 找不到对应路由,抛出警告。
  • 接口请求失败后,页面因没有数据渲染而空白。
  • 手动添加 http://localhost:3000 前缀时,服务端请求会先发送到 Nuxt 开发服务器,再通过 devProxy 转发到目标地址,所以能正常工作,但这种写法不够灵活。

解决方法

方法一:用环境变量区分服务端/客户端请求地址

这是最推荐的方式,兼顾开发/生产环境的灵活性:

  1. 在项目根目录创建 .env 文件:
# 服务端直接请求后端地址
NUXT_API_BASE_URL=http://localhost:8081/api
# 客户端请求Nuxt服务器,再通过devProxy转发
NUXT_PUBLIC_API_BASE_URL=/api
  1. 在 nuxt.config.ts 中配置 runtimeConfig:
export default defineNuxtConfig({
  runtimeConfig: {
    apiBaseUrl: process.env.NUXT_API_BASE_URL || '', // 服务端专用,不暴露给客户端
    public: {
      apiBaseUrl: process.env.NUXT_PUBLIC_API_BASE_URL || '' // 客户端可访问
    }
  },
  nitro: {
    devProxy: {
      "/api/": {
        target: "http://localhost:8081/",
        changeOrigin: true,
      },
    },
  },
  // 其他已有配置...
})
  1. 修改页面中的 useFetch 代码:
<script setup lang="ts">
const route = useRoute();
const id = route.params.id;
const config = useRuntimeConfig();

// 根据环境自动选择请求地址
const baseUrl = process.server ? config.apiBaseUrl : config.public.apiBaseUrl;

const { data: res, error } = await useFetch<Result<ProductDeatil>>(
  '/product/getProductById',
  { baseURL: baseUrl, query: { id } }
);
</script>

方法二:创建服务端API路由转发

通过 Nuxt 的服务端路由统一处理代理,无需依赖 devProxy,生产环境也适用:

  1. 在 server/api/product 目录下创建 getProductById.ts 文件:
export default defineEventHandler(async (event) => {
  // 获取请求参数
  const { id } = getQuery(event);
  // 直接请求后端接口
  return await $fetch('http://localhost:8081/api/product/getProductById', {
    query: { id }
  });
})
  1. 页面中的 useFetch 保持原有写法即可:
<script setup lang="ts">
const route = useRoute();
const id = route.params.id;

const { data: res, error } = await useFetch<Result<ProductDeatil>>(
  '/api/product/getProductById',
  { query: { id } }
);
</script>

方法三:直接在useFetch中区分环境(快速临时方案)

如果只是临时调试,可以直接在代码中判断环境:

<script setup lang="ts">
const route = useRoute();
const id = route.params.id;

const { data: res, error } = await useFetch<Result<ProductDeatil>>(
  process.server 
    ? 'http://localhost:8081/api/product/getProductById' 
    : '/api/product/getProductById',
  { query: { id } }
);
</script>

内容的提问来源于stack exchange,提问作者月上老狗

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:34:56