Next.js 13 App Router操作public目录JSON:POST接口报错排查
问题
使用Next.js 13 App Router对public目录下的internalData.json文件执行GET和POST操作时,GET接口正常,但POST接口报错:
error RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: 0
以下是当前代码:
import path from "path"; import { promises as fs } from "fs"; import { NextResponse } from "next/server"; export async function GET() { // Find the absolute path of the JSON directory const jsonDirectory = path.join(process.cwd(), "public"); // Read the JSON data file 'internalData.json' const fileContents = await fs.readFile( path.join(jsonDirectory, "internalData.json"), "utf8" ); // Parse the content to remove escape characters const jsonData = JSON.parse(fileContents); // Return the content of the data file in JSON format return NextResponse.json(jsonData); } export async function POST(request) { try { const jsonDirectory = path.join(process.cwd(), "public"); const fileContents = await fs.readFile( path.join(jsonDirectory, "internalData.json"), "utf8" ); const jsonData = JSON.parse(fileContents); const requestBody = await request.json(); const linkData = requestBody.links; jsonData.links = linkData; const updatedJsonData = JSON.stringify(jsonData, null, 2); await fs.writeFile( path.join(jsonDirectory, "internalData.json"), updatedJsonData, "utf8" ); const response = new NextResponse(); response.init({ status: 200, headers: { "Content-Type": "application/json", }, }); response.send(updatedJsonData); return response; } catch (error) { console.error("POST request error:", error); return NextResponse.error(error); } }
解决方案
错误原因
POST函数中手动实例化NextResponse并调用init的方式不符合Next.js的API规范,NextResponse的初始化逻辑与原生Response不同,导致状态码被错误设置为0,触发了ERR_HTTP_INVALID_STATUS_CODE错误。
修复后的POST代码
直接使用NextResponse.json()或NextResponse.text()构建响应,无需手动调用init和send:
export async function POST(request) { try { const jsonDirectory = path.join(process.cwd(), "public"); const fileContents = await fs.readFile( path.join(jsonDirectory, "internalData.json"), "utf8" ); const jsonData = JSON.parse(fileContents); const requestBody = await request.json(); const linkData = requestBody.links; jsonData.links = linkData; const updatedJsonData = JSON.stringify(jsonData, null, 2); await fs.writeFile( path.join(jsonDirectory, "internalData.json"), updatedJsonData, "utf8" ); // 直接返回JSON格式响应,自动设置200状态码和正确的Content-Type return NextResponse.json(JSON.parse(updatedJsonData), { status: 200 }); } catch (error) { console.error("POST request error:", error); // 返回错误信息和500状态码 return NextResponse.json({ error: error.message }, { status: 500 }); } }
额外提示
- Next.js 13 App Router中,
NextResponse提供了封装好的响应构建方法,无需手动实例化后初始化,这是和原生Response的核心区别之一。 - 直接操作public目录下的文件在生产环境需注意文件权限问题,且文件修改后不会触发Next.js静态资源的热更新,若需频繁动态修改数据,建议改用数据库或专门的文件存储方案。
内容的提问来源于stack exchange,提问作者Coke Ho
相关产品推荐
相关产品推荐

