在 nuxt 3 的服务端 api 路由中,无法通过 import() 动态导入 json 文件(因 es 模块要求路径为静态字符串),需改用 node.js 原生 fs 或 readfile 等运行时文件读取方式安全加载。
在 nuxt 3 的服务端 api 路由中,无法通过 import() 动态导入 json 文件(因 es 模块要求路径为静态字符串),需改用 node.js 原生 fs 或 readfile 等运行时文件读取方式安全加载。
在 Nuxt 3 的服务端 API(即 server/api/ 下的 .ts 文件)中,开发者常希望根据请求参数(如 ?path=home)动态加载对应 JSON 文件。但直接使用 await import(filePath) 并传入变量路径会失败——即使添加 { assert: { type: 'json' } },也会报错:
Module "file:///.../assets/json/article-1.json" needs an import assertion of type "json"
这是因为 ES 模块规范强制要求 import() 的模块说明符(specifier)必须是编译期可静态分析的字符串字面量,不支持变量、模板字符串或运行时拼接。因此,以下写法均非法:
// ❌ 错误:动态路径不被允许
await import(`./assets/json/${path}.json`, { assert: { type: 'json' } })
await import(filePath, { assert: { type: 'json' } })
✅ 推荐方案:使用 fs.promises.readFile(Node.js 原生异步 API)
Nuxt 3 的服务端环境默认运行于 Node.js(非浏览器),因此可安全使用 fs 模块。相比手动封装 Promise + 回调的写法,应优先采用现代 Promise 版本,并配合类型断言与路径校验提升健壮性:
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
import { promises as fs } from 'fs'
import { join, resolve } from 'path'
import { defineEventHandler, getQuery, createError } from 'h3'
export default defineEventHandler(async (event) => {
const query = getQuery(event)
const path = String(query.path || '').trim()
// ✅ 安全路径白名单校验(防止目录遍历攻击)
const allowedPaths = ['home', 'article-1', 'article-2', 'article-3', 'article-4', 'article-5', 'article-6']
if (!allowedPaths.includes(path)) {
throw createError({
statusCode: 400,
statusMessage: 'Invalid or unsupported path'
})
}
// ✅ 构建绝对路径(避免相对路径解析歧义)
const jsonPath = resolve(process.cwd(), 'assets', 'json', `${path}.json`)
try {
const data = await fs.readFile(jsonPath, '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 read JSON file',
cause: err
})
}
})
⚠️ 注意事项与最佳实践
- 禁止直接拼接用户输入到文件路径:务必通过白名单(如 allowedPaths)或正则校验(如 /^[a-z0-9\-]+$/i)过滤 path 参数,杜绝 ../../../etc/passwd 类路径遍历风险。
- 使用 resolve() 构建绝对路径:避免因工作目录变化导致路径解析错误;process.cwd() 在 Nuxt 中始终指向项目根目录。
- 显式指定编码 'utf8':readFile 返回 string 而非 Buffer,简化后续 JSON.parse() 步骤。
- 不要在服务端 import assets 下的 JSON:assets/ 目录在构建后不会被复制到服务端输出目录(仅用于客户端资源处理)。若需服务端访问静态 JSON,建议将数据文件移至 server/assets/ 或 data/ 目录(并确保该目录未被 .nuxtignore 排除)。
-
替代方案对比:
- import.meta.resolve() + fs.readFile:可用于动态解析路径,但复杂度高且非必需;
- 预加载所有 JSON 到内存:适用于小文件且数量固定,但违背“按需加载”原则;
- 使用 unenv 兼容层:Nuxt 内置,但 fs 已开箱即用,无需额外配置。
✅ 总结
动态加载服务端 JSON 的唯一合规路径是放弃 import(),转而使用 fs.promises.readFile 配合严格路径校验与错误处理。该方案符合 Node.js 运行时特性、规避模块系统限制,并具备生产级安全性与可维护性。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










