Next.js API路由使用Context报错:TypeError与JSON输入异常
问题原因与解决方案
核心问题
你犯了Next.js路由模型的基础错误:
/api路由是服务端运行的API端点,本质是Node.js环境下的后端代码,不能使用React客户端专属的useContext钩子,也不需要加'use client'指令。- 代码里只做了
console.log却没有返回合法响应,导致前端解析空内容时抛出SyntaxError: Unexpected end of JSON input;而强制在服务端环境用客户端钩子,直接触发了TypeError: r is not a function。
具体解决步骤
1. 彻底移除/api路由中的客户端代码
把'use client'和useContext全部删掉,换用HTTP标准方式传递sdr值到服务端。
方法一:通过请求参数/请求体传递(通用场景)
- 前端客户端组件(可以正常用
useContext的地方):
'use client' import { useContext } from 'react' import { calendarInsertContext } from './calendarInsertContext' export default function YourComponent() { const { sdr } = useContext(calendarInsertContext) const callApi = async () => { // 方式1:作为URL查询参数传递 const res = await fetch(`/api/your-route?sdr=${encodeURIComponent(sdr)}`) // 方式2:作为POST请求体传递(更适合敏感/复杂数据) // const res = await fetch('/api/your-route', { // method: 'POST', // headers: { 'Content-Type': 'application/json' }, // body: JSON.stringify({ sdr }) // }) const data = await res.json() // 处理返回结果 } return <button onClick={callApi}>调用API</button> }
- 服务端/api路由文件:
// app/api/your-route/route.js export async function GET(req) { // 从查询参数读取sdr const { searchParams } = new URL(req.url) const sdr = searchParams.get('sdr') console.log('sdr backend: ', sdr) // 必须返回合法响应,否则前端会报错 return Response.json({ sdr }) } // 如果用POST请求,对应写POST方法 export async function POST(req) { const { sdr } = await req.json() console.log('sdr backend: ', sdr) return Response.json({ success: true }) }
方法二:通过Cookie传递(敏感用户数据场景)
如果sdr是用户身份类敏感数据,存到Cookie里更安全:
- 前端客户端组件设置Cookie:
'use client' import { useContext } from 'react' import { calendarInsertContext } from './calendarInsertContext' export default function YourComponent() { const { sdr } = useContext(calendarInsertContext) // 设置Cookie(可借助js-cookie库简化操作) document.cookie = `sdr=${encodeURIComponent(sdr)}; path=/;` return <button onClick={() => fetch('/api/your-route')}>调用API</button> }
- 服务端/api路由读取Cookie:
export async function GET(req) { const cookieHeader = req.headers.get('cookie') const sdr = cookieHeader?.split('; ').find(row => row.startsWith('sdr='))?.split('=')[1] if (sdr) { console.log('sdr backend: ', decodeURIComponent(sdr)) } return Response.json({ sdr: decodeURIComponent(sdr) }) }
2. 必做:确保API路由返回合法响应
不管用哪种方式,GET/POST函数必须返回Response对象(比如Response.json()、Response.text()),否则前端会因为解析空内容抛出JSON错误。
关键总结
- Next.js的
/api路由是纯服务端代码,和React客户端的Context、状态钩子完全不兼容,不能跨端直接共享数据。 - 客户端到服务端的数据传递,只能依赖HTTP协议的标准方式:URL参数、请求体、Cookie、请求头。
内容的提问来源于stack exchange,提问作者Maria Eduarda
相关产品推荐
相关产品推荐

