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

如何编写Next.js 13服务端与客户端通用的请求工具?

实现Next.js 13 App Router与Laravel Sanctum的通用请求工具

要解决服务端专属API在客户端组件报错的问题,核心思路是环境隔离+动态导入,避免在客户端执行服务端代码。以下是具体实现方案:

1. 封装通用请求函数

创建工具文件(如utils/api-fetch.ts),通过环境判断分支处理服务端/客户端的请求配置,同时动态导入服务端专属模块:

import type { RequestInit } from 'node-fetch';
import Cookies from 'js-cookie';

// 扩展请求配置类型,允许自定义headers
type ApiFetchOptions = Omit<RequestInit, 'headers'> & {
  headers?: Record<string, string>;
};

export async function apiFetch(url: string, options: ApiFetchOptions = {}) {
  const isServer = typeof window === 'undefined';
  const fetchOptions: RequestInit = { ...options };

  if (isServer) {
    // 服务端环境:动态导入Next.js服务端API,避免客户端加载
    const { cookies, headers } = await import('next/headers');
    const cookieStore = cookies();
    const requestHeaders = headers();

    fetchOptions.headers = {
      ...fetchOptions.headers,
      'Cookie': cookieStore.toString(),
      'Referer': requestHeaders.get('referer') ?? '',
      'X-Xsrf-Token': cookieStore.get('XSRF-TOKEN')?.value || '',
    };
  } else {
    // 客户端环境:使用浏览器Cookie和标准请求头
    fetchOptions.headers = {
      ...fetchOptions.headers,
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'Origin': process.env.NEXT_PUBLIC_APP_URL || '',
      'X-Requested-With': 'XMLHttpRequest',
      'X-Xsrf-Token': Cookies.get('XSRF-TOKEN') || '',
    };
    fetchOptions.credentials = 'include';
  }

  return fetch(url, fetchOptions);
}

2. 在组件中使用

客户端组件('use client')

'use client';

import { apiFetch } from '@/utils/api-fetch';

async function UserProfile() {
  const response = await apiFetch('/api/auth/user');
  const user = await response.json();

  return <div>当前用户:{user.name}</div>;
}

export default UserProfile;

服务端组件

import { apiFetch } from '@/utils/api-fetch';

async function Dashboard() {
  const response = await apiFetch('/api/dashboard/stats');
  const stats = await response.json();

  return <div>今日访问量:{stats.today_visits}</div>;
}

export default Dashboard;

3. 关键注意点

  • 环境判断:用typeof window === 'undefined'区分服务端/客户端,这是Next.js中安全可靠的判断方式。
  • 动态导入:服务端环境下动态导入next/headers,确保客户端组件不会加载该模块,避免调用服务端专属函数报错。
  • Cookie处理:客户端依赖浏览器自动携带Cookie(通过credentials: 'include'),服务端则手动拼接Cookie字符串。
  • 配置兼容性:确保Laravel Sanctum的SANCTUM_STATEFUL_DOMAINS环境变量包含你的Next.js域名,否则认证会失效。
  • 灵活性:函数支持传入自定义headers和请求配置,满足不同场景的需求。

内容的提问来源于stack exchange,提问作者grazdev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 02:52:24