Next.js 15 全栈开发系列之内置 API 和工具

文摘   2024-11-10 07:35   湖北  

Next.js 作为现代 React 应用开发的重要框架,提供了丰富的 API 和工具来帮助开发者构建高性能、可扩展的 Web 应用。本文将全面介绍 Next.js 中的各类 API,包括数据获取、路由处理、元数据生成等核心功能。

一、数据获取与缓存

1. fetch API

Next.js 增强了原生的 fetch API,添加了自动缓存和重新验证功能。

// 1. 基础请求
const response = await fetch('https://api.example.com/data');
const data = await response.json();

// 2. 带缓存控制的请求
const cachedResponse = await fetch('https://api.example.com/data', {
  next: { revalidate3600 } // 1小时后重新验证
});

// 3. 禁用缓存的实时请求
const realtimeResponse = await fetch('https://api.example.com/data', {
  cache'no-store'
});

关键特性:

  • • 自动请求去重

  • • 内置缓存机制

  • • 支持增量静态再生成(ISR)

  • • 可配置的缓存策略

使用建议:

  • • 静态数据使用默认缓存

  • • 频繁更新的数据设置适当的重新验证时间

  • • 实时数据禁用缓存

2. 缓存控制

unstable_cache

用于自定义缓存行为的高级 API。

import { unstable_cache } from 'next/cache';

const getCachedData = unstable_cache(
  async (keystring) => {
    const data = await fetchData(key);
    return data;
  },
  ['cache-key'],
  {
    revalidate3600,
    tags: ['data']
  }
);

主要功能:

  • • 自定义缓存键

  • • 可配置的缓存时间

  • • 支持缓存标签

  • • 条件性缓存

unstable_noStore

用于显式禁用缓存的 API。

import { unstable_noStore } from 'next/cache';

async function getDynamicData() {
  unstable_noStore();
  const data = await fetch('/api/data');
  return data.json();
}

使用场景:

  • • 实时数据获取

  • • 用户特定的内容

  • • 动态API响应

3. 重新验证

revalidatePath

用于重新验证特定路径的缓存。

import { revalidatePath } from 'next/cache';

async function updateContent() {
  await saveContent();
  revalidatePath('/blog/[slug]');
}

revalidateTag

基于标签重新验证缓存。

import { revalidateTag } from 'next/cache';

async function updateProducts() {
  await saveProducts();
  revalidateTag('products');
}

重新验证策略:

  • • 按需重新验证

  • • 基于时间的自动重新验证

  • • 基于标签的选择性重新验证

二、请求处理

1. Cookies 管理

使用 cookies API 在服务器端安全地处理 cookie。

import { cookies } from 'next/headers';

// 设置 cookie
function setUserPreferences() {
  cookies().set('theme''dark', {
    httpOnlytrue,
    secure: process.env.NODE_ENV === 'production',
    sameSite'strict',
    maxAge7 * 24 * 60 * 60 // 一周
  });
}

// 读取 cookie
function getUserPreferences() {
  const theme = cookies().get('theme');
  return theme?.value;
}

// 删除 cookie
function resetPreferences() {
  cookies().delete('theme');
}

安全最佳实践:

  • • 使用 httpOnly 防止 XSS 攻击

  • • 生产环境启用 secure 选项

  • • 设置适当的 sameSite 策略

2. Headers 处理

用于访问和操作 HTTP 头信息。

import { headers } from 'next/headers';

function getRequestMetadata() {
  const headersList = headers();
  return {
    userAgent: headersList.get('user-agent'),
    contentType: headersList.get('content-type'),
    authorization: headersList.get('authorization')
  };
}

常用场景:

  • • 获取客户端信息

  • • 处理认证头

  • • 实现内容协商

3. Request 和 Response

NextRequest

扩展的请求对象,提供额外的便利方法。

import { NextRequestNextResponse } from 'next/server';

export async function middleware(requestNextRequest) {
  // 获取地理位置信息
  const country = request.geo?.country;
  
  // 获取 URL 信息
  const { pathname, searchParams } = request.nextUrl;
  
  // 获取 cookies
  const token = request.cookies.get('token');
}

NextResponse

用于构建响应的工具类。

export async function handler(requestNextRequest) {
  // JSON 响应
  return NextResponse.json({ message'Success' });
  
  // 重定向
  return NextResponse.redirect(new URL('/login', request.url));
  
  // 修改响应头
  const response = NextResponse.next();
  response.headers.set('x-custom-header''value');
  return response;
}

三、元数据生成

1. generateMetadata

用于生成动态的页面元数据。

import { Metadata } from 'next';

export async function generateMetadata(
  { params }: { params: { id: string } }
): Promise<Metadata> {
  const product = await getProduct(params.id);
  
  return {
    title: product.name,
    description: product.description,
    openGraph: {
      images: [{ url: product.image }],
    },
  };
}

支持的元数据:

  • • 基本 SEO 标签

  • • Open Graph 标签

  • • Twitter Cards

  • • 图标和主题色

2. generateImageMetadata

生成动态图片元数据。

export async function generateImageMetadata() {
  const products = await getProducts();
  
  return products.map((product) => ({
    id: product.id,
    alt: product.name,
    size: { width1200height630 },
    contentType'image/jpeg',
  }));
}

用途:

  • • 动态图片尺寸

  • • SEO 优化

  • • 社交媒体预览

3. generateSitemaps

生成动态站点地图。

export async function generateSitemaps() {
  const products = await getAllProducts();
  
  return products.map((product) => ({
    url`/products/${product.id}`,
    lastModified: product.updatedAt,
    changeFrequency'weekly',
    priority0.8,
  }));
}

SEO 优化:

  • • 自动站点地图生成

  • • 搜索引擎优化

  • • 内容可发现性

四、路由与导航

1. 路由控制

redirect

用于临时重定向(302)。

import { redirect } from 'next/navigation';

async function handleAuth() {
  const user = await getUser();
  if (!user) {
    redirect('/login');
  }
}

permanentRedirect

用于永久重定向(308)。

import { permanentRedirect } from 'next/navigation';

export default function OldPage() {
  permanentRedirect('/new-page');
}

notFound

触发 404 错误页面。

import { notFound } from 'next/navigation';

async function getProduct(idstring) {
  const product = await fetchProduct(id);
  if (!product) {
    notFound();
  }
  return product;
}

2. 客户端导航

一系列用于客户端导航的 Hooks。

'use client';

import {
  useParams,
  usePathname,
  useRouter,
  useSearchParams,
  useSelectedLayoutSegment,
  useSelectedLayoutSegments
from 'next/navigation';

export default function Navigation() {
  const params = useParams();
  const pathname = usePathname();
  const router = useRouter();
  const searchParams = useSearchParams();
  const segment = useSelectedLayoutSegment();
  const segments = useSelectedLayoutSegments();
  
  return (
    <nav>
      <div>当前路径: {pathname}</div>
      <div>参数: {JSON.stringify(params)}</div>
      <div>查询参数: {searchParams.get('q')}</div>
      <div>当前段: {segment}</div>
      <div>所有段: {segments.join('/')}</div>
      
      <button onClick={() => router.push('/about')}>
        关于页面
      </button>
    </nav>

  );
}

主要功能:

  • • 路由参数获取

  • • 路径操作

  • • 编程式导航

  • • 布局段控制

五、性能优化

1. Draft Mode

预览模式支持。

import { draftMode } from 'next/headers';

async function getContent(slugstring) {
  const { isEnabled } = draftMode();
  
  return isEnabled
    ? await getDraftContent(slug)
    : await getPublishedContent(slug);
}

2. 性能监控

'use client';

export function useReportWebVitals() {
  useReportWebVitals((metric) => {
    // 发送性能指标到分析服务
    sendToAnalytics({
      name: metric.name,
      value: metric.value,
      id: metric.id,
    });
  });
}

监控指标:

  • • FCP (First Contentful Paint)

  • • LCP (Largest Contentful Paint)

  • • FID (First Input Delay)

  • • CLS (Cumulative Layout Shift)

六、用户体验

1. Viewport 配置

自定义视口设置。

import { Viewport } from 'next';

export function generateViewport(): Viewport {
  return {
    width'device-width',
    initialScale1,
    themeColor: [
      { media'(prefers-color-scheme: light)'color'#ffffff' },
      { media'(prefers-color-scheme: dark)'color'#000000' },
    ],
    viewportFit'cover',
  };
}

2. User Agent 检测

import { userAgent } from 'next/server';

export function middleware(requestNextRequest) {
  const { device, engine, browser } = userAgent(request);
  
  // 设备适配
  if (device.type === 'mobile') {
    return NextResponse.redirect(new URL('/mobile', request.url));
  }
}

七、错误处理

unstable_rethrow

用于增强错误处理能力。

import { unstable_rethrow } from 'next/dist/client/components/react-dev-overlay/internal/error-overlay-reducer';

async function fetchData() {
  try {
    const data = await riskyOperation();
    return data;
  } catch (error) {
    unstable_rethrow(error, {
      componentStacktrue,
      digest'custom-error',
    });
  }
}

  🚧 提示:

  1. 1. 部分 API 可能处于实验阶段

  2. 2. 某些功能可能需要额外配置

  3. 3. 始终查看官方文档获取最新信息

更多关于 Next.js的全栈内容请点击下面的合集


字节笔记本
专注于科技领域的分享,AIGC,全栈开发,产品运营
 最新文章