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

NextJS 13 AppDir:如何实现服务器端获取数据的搜索筛选?

在Next.js 13 App Dir中实现服务器端数据的搜索筛选

核心结论

服务器组件完全可以访问URL的Search Params,这是实现服务器端数据筛选的标准方案,既安全又符合App Dir的架构设计。

服务器端能访问的内容

在App Dir的服务器组件中,你可以直接获取:

  • 组件props中的searchParams(URL查询参数)
  • cookies(通过cookies()函数)
  • 请求头(通过headers()函数)
  • 路径参数(比如/posts/[id]中的id)

这些信息都是服务器端处理的,不会暴露给客户端,敏感凭证(如Bearer Token)可以存在服务器环境变量中,无需让客户端接触。

实现步骤

1. 客户端搜索组件(处理输入并更新Search Params)

因为需要处理输入状态,搜索栏必须是客户端组件(加'use client'指令),它的作用只是更新URL的搜索参数,不直接请求数据:

'use client';

import { useRouter } from 'next/navigation';
import { useState } from 'react';

export default function SearchBar() {
  const [query, setQuery] = useState('');
  const router = useRouter();

  const handleSearch = (e: React.FormEvent) => {
    e.preventDefault();
    // 更新URL的search params,触发服务器组件重新渲染
    router.push(`/?search=${encodeURIComponent(query)}`);
  };

  return (
    <form onSubmit={handleSearch}>
      <input
        type="text"
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder="搜索..."
      />
      <button type="submit">搜索</button>
    </form>
  );
}

2. 服务器页面组件(接收参数并筛选数据)

服务器组件通过props获取searchParams,用这个参数去调用后端API(服务器端调用,凭证存在环境变量):

import SearchBar from './SearchBar';

// 服务器组件,自动接收searchParams props
export default async function Home({ searchParams }: { searchParams: { search?: string } }) {
  const searchQuery = searchParams.search || '';
  
  // 服务器端调用后端API,使用环境变量中的凭证
  const res = await fetch(`https://your-api.com/data?search=${encodeURIComponent(searchQuery)}`, {
    headers: {
      Authorization: `Bearer ${process.env.API_TOKEN}`, // 这个token存在服务器环境变量,客户端看不到
    },
  });
  const data = await res.json();

  return (
    <div>
      <SearchBar />
      <ul>
        {data.map((item: any) => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}

为什么客户端直接请求不安全?

如果在客户端直接调用后端API,你必须把Bearer Token暴露在客户端代码中(哪怕存在NEXT_PUBLIC_环境变量,也会被打包到客户端JS里),攻击者可以轻松获取这个token并冒充用户请求API。而通过服务器端代理请求,token只存在服务器环境中,客户端完全接触不到,安全性大幅提升。

其他可选方案:表单POST提交

如果不想用URL参数(比如搜索内容敏感),可以用App Dir的服务器Action处理表单提交:

'use client';

import { useFormState } from 'react-dom';
import { searchAction } from './actions';

export default function SearchBar() {
  const [state, formAction] = useFormState(searchAction, null);

  return (
    <form action={formAction}>
      <input type="text" name="search" placeholder="搜索..." />
      <button type="submit">搜索</button>
    </form>
  );
}

对应的服务器Action:

'use server';

export async function searchAction(prevState: any, formData: FormData) {
  const searchQuery = formData.get('search') as string;
  
  // 服务器端调用API,逻辑和之前一致
  const res = await fetch(`https://your-api.com/data?search=${encodeURIComponent(searchQuery)}`, {
    headers: {
      Authorization: `Bearer ${process.env.API_TOKEN}`,
    },
  });
  const data = await res.json();
  
  return data;
}

然后在服务器组件中使用这个Action的结果即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 16:16:25