如何将Vercel部署的Next.js项目中JSON文件改为可读写?
解决Vercel部署Next.js后API写入JSON文件的只读文件系统错误
问题本质
Vercel的Serverless函数运行环境是只读文件系统,你尝试写入的/var/task/public/database/azalar.json属于部署时打包的静态资源目录,完全不支持写入操作。修改GitHub仓库设置无法解决问题,因为部署后的运行环境由Vercel管控,和仓库配置无关。
可行解决方案
你需要放弃直接写入本地JSON文件的方式,改用持久化存储服务,以下是几种实用方案:
1. Vercel官方KV存储(推荐)
Vercel集成的KV数据库适合存储JSON格式的键值数据,配置和使用都很简单:
- 在Vercel控制台开启KV存储服务
- 安装
@vercel/kv包后,在API路由中读写数据:import { kv } from '@vercel/kv'; export default async function handler(req, res) { if (req.method === 'POST') { // 写入数据 await kv.set('azalar-data', req.body); // 读取数据(示例) const storedData = await kv.get('azalar-data'); res.status(200).json(storedData); } }
2. 第三方数据库
像MongoDB、PostgreSQL、Firebase Firestore这类数据库,都能和Next.js API路由无缝对接:
- 以MongoDB为例,安装
mongoose包后实现数据操作:import mongoose from 'mongoose'; // 连接数据库(环境变量存连接字符串) await mongoose.connect(process.env.MONGODB_URI); // 定义数据结构 const AzalarSchema = new mongoose.Schema({ // 按需定义你的字段,比如username: String }); const Azalar = mongoose.model('Azalar', AzalarSchema); export default async function handler(req, res) { if (req.method === 'POST') { const newRecord = new Azalar(req.body); await newRecord.save(); res.status(201).json(newRecord); } }
3. 云存储服务
如果只是需要存储JSON文件,AWS S3、Cloudflare R2这类云存储服务是合适选择,通过SDK上传修改后的文件:
- 以AWS S3为例,安装
aws-sdk包后实现上传:import AWS from 'aws-sdk'; const s3 = new AWS.S3({ accessKeyId: process.env.AWS_ACCESS_KEY, secretAccessKey: process.env.AWS_SECRET_KEY, }); export default async function handler(req, res) { if (req.method === 'POST') { const jsonContent = JSON.stringify(req.body); await s3.putObject({ Bucket: '你的存储桶名称', Key: 'azalar.json', Body: jsonContent, ContentType: 'application/json', }).promise(); res.status(200).json({ success: true }); } }
额外提醒
- Serverless函数的
/tmp临时目录虽然可写,但数据不会持久化,实例销毁后就会丢失,仅适合临时缓存,不能用来存储长期数据。 - 所有敏感信息(数据库密钥、存储服务密钥)必须放在Vercel的环境变量中,禁止硬编码在代码里。
内容的提问来源于stack exchange,提问作者Necoo33
相关产品推荐
相关产品推荐

