ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

如何用 puter.fs.upload() 上传目录并处理 Node.js 环境下的 batch_upload_failed?

如何用 puter.fs.upload() 上传目录并处理 Node.js 环境下的 batch_upload_failed? 如何用 puter.fs.upload() 上传目录并处理 Node.js 环境下的 batch_upload_failed【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter在 Node.js 里用 Puter.js 上传文件时很多人会先把本地目录直接传给puter.fs.upload()然后收到一个带code: batch_upload_failed的 rejection。这不是网络故障而是平台差异导致的目录上传拖拽的目录条目或createFileParent只在websites和apps平台受支持在nodejs和workers上上传走的是旧版 batch 接口它无法创建目录树所以目录上传会直接以batch_upload_failed被拒绝。要完成「把本地一个目录连同子目录整体传到 Puter 文件系统」这件事正确路径是先用puter.fs.mkdir()建好远端目录树再按目录分组调用puter.fs.upload(files, dirPath)上传文件最后用puter.fs.readdir()核对结果。本文按这条主路径给出完整可运行的 Node.js 示例并说明如何区分 batch 上传的三个 rejection code。为什么 Node.js 下直传目录会得到 batch_upload_failedputer.fs.upload()的items参数接受InputFileList、FileList、File对象数组或Blob对象数组。文档对平台差异的说明是Onnodejsandworkersthe upload goes through an older batch endpoint that cannot create the directory tree, so a directory upload rejects withbatch_upload_failed.也就是说batch_upload_failed表示「所有操作都失败了没有任何东西被写入」它的成因在 Node.js/Workers 环境里就是目标目录结构没有提前建好。同一份文档还定义了另外两个 batch rejection codebatch_upload_failed— 全部操作失败什么都没写入batch_upload_partially_failed— 部分成功、部分失败。failedCount和totalCount给出数量results按发送顺序保留每个操作的结果batch_upload_no_results— 请求本身成功但服务端没有回报具体写了什么。此外无论走哪条接口upload 的 Promise 都不会「部分成功地 resolve」任一部分失败都会 reject。rejection 一定带message如果是单个文件失败而非整个请求失败还带failedItems数组每项含path、message服务端给出的话还有code和status。部分失败的上传不会回滚已经写入的文件仍然留在远端。一个常见整体失败原因是超出账户存储配额此时 rejection 带code: storage_limit_reached和status: 413。准备 Node.js 环境按 supported-platforms.md 的说明Puter.js 支持 Node.js。安装并初始化npm install heyputer/puter.jsimport { init } from heyputer/puter.js/src/init.cjs; const puter init(process.env.puterAuthToken); // 使用你的 auth token其中process.env.puterAuthToken是文档示例使用的鉴权 token换成你自己的环境变量即可。如果你的运行环境可以打开浏览器例如 CLI 工具场景文档提供了用浏览器登录获取 token 的替代方式import { init, getAuthToken } from heyputer/puter.js/src/init.cjs; const authToken await getAuthToken(); // performs browser based auth const puter init(authToken);主路径先 mkdir 建树再分组上传puter.fs.mkdir(path, options)支持createMissingParents: true一次创建缺失的整条父目录链返回创建目录的FSItem。相对路径相对于 app 根目录解析。puter.fs.upload(items, dirPath)的dirPath指定上传目标目录未设置时上传到 app 根目录。下面的脚本完成完整任务遍历本地目录./data为每个本地子目录在远端建对应目录再按目录分组上传文件并在 catch 中区分三个 batch code 与逐项失败信息。import { init } from heyputer/puter.js/src/init.cjs; import { readdirSync, readFileSync } from node:fs; import { join, relative } from node:path; const puter init(process.env.puterAuthToken); const LOCAL_DIR ./data; // 本地要上传的目录 const REMOTE_ROOT uploads/2026-09; // 远端根目录相对路径相对 app 根目录解析 // 遍历本地目录标准 Node.js 代码不是 Puter API // 返回 [{ file: File, relDir: 相对 LOCAL_DIR 的父目录 }...] function collectFiles(localDir) { const out []; for (const entry of readdirSync(localDir, { recursive: true, withFileTypes: true })) { if (!entry.isFile()) continue; const abs join(localDir, entry.name); out.push({ file: new File([readFileSync(abs)], entry.name), // File 为 Node.js 标准全局对象 relDir: relative(localDir, abs), }); } return out; } const entries collectFiles(LOCAL_DIR); // 1) 为每个本地子目录创建远端目录含缺失的父目录 const remoteDirs [...new Set(entries.map((e) e.relDir . ? REMOTE_ROOT : ${REMOTE_ROOT}/${e.relDir} ))]; for (const dir of remoteDirs) { await puter.fs.mkdir(dir, { createMissingParents: true }); } // 2) 按目标目录分组上传 try { for (const dir of remoteDirs) { const group entries.filter((e) (e.relDir . ? REMOTE_ROOT : ${REMOTE_ROOT}/${e.relDir}) dir ); const results await puter.fs.upload( group.map((g) g.file), dir, { progress: (operationId, progress) console.log(${dir}: ${Math.round(progress)}%) } ); // 成功单文件 resolve 为 FSItem多文件 resolve 为 FSItem 数组 console.log((Array.isArray(results) ? results : [results]).map((r) r.path)); } } catch (err) { if (err.code batch_upload_failed) { // 全部失败什么都没写入整批重传或先排查原因 console.error(整批失败未写入任何文件:, err.message); } else if (err.code batch_upload_partially_failed) { // 部分成功results 按发送顺序保留每个操作的结果 console.error(本批 ${err.failedCount}/${err.totalCount} 个操作失败); for (const r of err.results) console.log(r); // 已成功的部分不会回滚重传时只需处理失败项 } else if (err.code batch_upload_no_results) { // 请求成功但服务端未回报写入明细用 readdir 核对实际写入 console.error(服务端未回报写入明细:, err.message); } else if (err.code storage_limit_reached) { // 超出账户存储配额status 413 console.error(超出存储配额:, err.message); } else if (err.failedItems) { // 单个文件级别的失败逐项含 path / message可能有 code / status for (const item of err.failedItems) console.error(item.path, item.message, item.code); } else { console.error(上传失败:, err.message); } }示例中的./data、uploads/2026-09是本地/远端路径占位替换成你自己的目录即可progress回调是 upload 文档列出的官方回调签名是(operationId, progress)progress为 0–100 的百分比。验证上传结果两种验证手段都来自文档upload 的返回值成功 resolve 的FSItem或数组带有path打印出来即可确认文件落在哪个位置。列目录核对puter.fs.readdir(path)返回目录内所有条目的FSItem数组文档示例即打印每个条目的item.pathconst items await puter.fs.readdir(REMOTE_ROOT, { recursive: true }); items.forEach((item) console.log(item.path));列出结果里能看到远端目录树和全部文件路径即说明「mkdir 建树 分组上传」这条链路完成。平台限制与注意事项目录上传只在websites和apps平台可用。在浏览器端如 upload 文档的示例可以直接传目录条目还可以给 upload 传createMissingParents: trueupload 的该选项默认falseNode.js/Workers 端必须走本文的 mkdir 文件上传路径没有第二种写法。部分失败不回滚batch_upload_partially_failed之后已写入的文件保留在远端。重传前建议先用readdir或failedItems里的path区分哪些文件需要补传。重名行为upload 默认overwrite: false、dedupeName: true重名时自动去重改名mkdir 的dedupeName默认是false。重传同一批文件时如需覆盖同名文件显式传overwrite: true。完整参数与回调说明见 puter.fs.upload() 文档、puter.fs.mkdir() 文档 和 puter.fs.readdir() 文档。【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表