在 Nuxt 3 的 server/api 路由中,无法通过动态字符串调用 import() 加载 JSON 文件(因 ES 模块导入要求静态路径),需改用 Node.js 原生 fs.readFile 或其 Promise 版本安全读取并解析。
在 nuxt 3 的服务端 api 路由中,无法通过动态字符串调用 `import()` 加载 json 文件(因 es 模块导入要求静态路径),需改用 node.js 原生 `fs.readfile` 或其 promise 版本安全读取并解析。
在 Nuxt 3 的服务端 API(即 server/api/xxx.ts)中,开发者常希望根据请求参数(如 ?path=home)动态加载对应 JSON 文件(如 assets/json/home.json)。但直接使用 await import(filePath, { assert: { type: 'json' } }) 会失败,并抛出错误:
Module "file:///.../home.json" needs an import assertion of type "json"
根本原因在于:ES 模块的 import() 是静态分析语法,即使在运行时调用,其模块说明符(即路径)也必须是 可静态确定的字符串字面量。变量、模板字符串或枚举值均不满足该条件——Vite/Nitro 在构建时无法预解析这些路径,因此拒绝处理,且 assert 选项在此场景下无效。
✅ 正确解法:使用 Node.js 原生 fs(文件系统)API 读取并解析 JSON
Nitro 服务端环境默认支持 CommonJS 和 Node.js 内置模块(包括 fs),推荐使用 fs.promises.readFile(更简洁、无回调嵌套):
// server/api/page.ts
import { promises as fs } from 'fs'
import { join } from 'path'
import { defineEventHandler, getQuery } from 'h3'
export default defineEventHandler(async (event) => {
const query = getQuery(event)
const path = String(query.path || '').trim()
// ✅ 安全校验:仅允许字母、数字、短横线、下划线
if (!/^[a-z0-9_-]+$/i.test(path)) {
throw createError({
statusCode: 400,
statusMessage: 'Invalid path parameter'
})
}
const filePath = join(process.cwd(), 'assets', 'json', `${path}.json`)
try {
const data = await fs.readFile(filePath, 'utf8')
return JSON.parse(data) // 自动类型推断为 any;建议配合 zod 或 interface 做运行时校验
} catch (err: any) {
if (err.code === 'ENOENT') {
throw createError({
statusCode: 404,
statusMessage: `JSON file not found: ${path}.json`
})
}
throw createError({
statusCode: 500,
statusMessage: 'Failed to load JSON file',
cause: err
})
}
})
? 关键要点与最佳实践:
- 路径拼接务必使用 path.join():避免手动拼接 / 导致跨平台路径错误(Windows vs Unix);
- 严格校验输入参数:防止路径遍历攻击(如 path=../../etc/passwd),正则白名单是最简有效方式;
- 使用 process.cwd() 定位项目根目录:确保 assets/json/ 相对路径始终正确(Nitro 构建后仍可访问源码目录下的 assets/);
- 错误分类处理:区分 ENOENT(文件不存在)与其它 I/O 错误,返回语义化状态码;
- 避免 require() 或 fs.readFileSync:同步方法会阻塞事件循环,降低并发性能;
- ⚠️ 注意:assets/ 目录不会自动被 Nitro 打包进生产服务端产物,但 server/api 路由运行在 Node.js 环境下,可直接读取开发时存在的文件。若需确保生产环境可用,请将 JSON 文件移至 server/assets/ 或通过 nitro.plugins 显式声明为服务端资产。
? 进阶建议:
如需强类型保障,可搭配 Zod 对 JSON 结构做运行时验证:
import { z } from 'zod'
const PageSchema = z.object({ title: z.string(), content: z.string() })
// … 在 JSON.parse 后添加:
const parsed = JSON.parse(data)
const page = PageSchema.parse(parsed) // 类型安全 + 自动校验
综上,动态 JSON 加载应放弃 import() 思路,转向 fs.promises.readFile + JSON.parse 组合,并辅以路径校验与错误处理——这是 Nuxt 3 / Nitro 服务端环境下最可靠、可维护且符合安全规范的实现方式。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











