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

Next.js App Router下表单提交后向服务端页面传参方案咨询

解决方案

核心思路

采用POST请求+服务器端加密会话的方式传递敏感数据:客户端表单提交数据到后端接口存入加密会话,服务端结果页从会话中读取数据,既避免URL暴露敏感信息,又符合Next.js App Router服务端组件的限制。


步骤1:改造客户端表单提交逻辑

你的客户端表单组件保持'use client',通过fetch发起POST请求把数据存入会话,再跳转到结果页:

'use client';

export default function SearchForm() {
  const handleSubmit = async (e) => {
    e.preventDefault();
    const formData = new FormData(e.target);
    const searchPayload = Object.fromEntries(formData);
    
    // 把表单数据提交到会话存储接口
    await fetch('/api/save-search', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(searchPayload),
    });
    
    // 跳转到结果页
    window.location.href = '/results';
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="origin" placeholder="出发地" />
      <input type="text" name="destination" placeholder="目的地" />
      {/* 敏感的当前位置字段,用hidden存储 */}
      <input type="hidden" name="currentLocation" value={userCurrentLocation} />
      <button type="submit">开始搜索</button>
    </form>
  );
}

步骤2:创建会话存储的API路由

在app/api/save-search/route.ts中实现POST接口,用iron-session(轻量加密会话库)存储数据:

import { ironSession } from 'iron-session/edge';
import { NextRequest, NextResponse } from 'next/server';

// 会话配置
const sessionConfig = {
  cookieName: 'travel-search-session',
  password: process.env.SESSION_ENCRYPT_KEY!, // 从环境变量取加密密钥,至少32位
  cookieOptions: {
    secure: process.env.NODE_ENV === 'production', // 生产环境开启HTTPS
    httpOnly: true, // 禁止客户端JS读取,提升安全性
  },
};

export async function POST(request: NextRequest) {
  const searchData = await request.json();
  const res = NextResponse.json({ success: true });
  
  // 初始化会话并存储数据
  const session = await ironSession(sessionConfig).get(res);
  session.searchData = searchData;
  await session.save();
  
  return res;
}

步骤3:服务端结果页读取会话数据

在app/results/page.js(服务端组件)中,从会话读取数据后调用Python后端:

import { ironSession } from 'iron-session/edge';
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';

export default async function ResultsPage() {
  // 从cookie获取会话
  const session = await ironSession({
    cookieName: 'travel-search-session',
    password: process.env.SESSION_ENCRYPT_KEY!,
    cookieOptions: {
      secure: process.env.NODE_ENV === 'production',
    },
  }).get(cookies());

  const searchData = session.searchData;
  // 无数据则重定向回首页
  if (!searchData) return redirect('/');

  // 调用Python后端接口
  const backendRes = await fetch('https://your-python-backend.com/travel-search', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(searchData),
  });
  const searchResults = await backendRes.json();

  // 渲染结果内容
  return (
    <div className="results-container">
      <h1>搜索结果</h1>
      {/* 渲染searchResults数据 */}
    </div>
  );
}

注意事项

  • 会话密钥要存在环境变量中,不要硬编码,确保安全性。
  • 可以在结果页渲染完成后清除会话数据,避免用户刷新页面重复使用旧数据:session.destroy()。
  • 若不想用iron-session,也可以用NextAuth的会话功能,逻辑类似。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 02:35:34