跳到主要内容

initLocalStorageServer(options)

initLocalStorageServer 函数是用于处理从用户设备直接上传文件到你的 Blocklet 本地存储的核心中间件。它利用了强大的 Tus 可续传上传协议,确保上传过程可靠,并能在网络中断后恢复。

initLocalStorageServer 函数是用于处理从用户设备直接上传文件到你的 Blocklet 本地存储的核心中间件。它利用了强大的 Tus 可续传上传协议,确保上传过程可靠,并能在网络中断后恢复。

该中间件负责接收文件块,在服务器上将它们组装成完整的文件,并在上传完成后触发回调,以便你处理文件元数据。

工作原理

下图说明了当用户使用连接到带有 initLocalStorageServer 后端的 Uploader 组件上传文件时的典型数据流。

基本用法

首先,在你的 Express 应用程序中初始化该中间件,并将其挂载到特定路由上。最关键的选项是 onUploadFinish,你将在这里定义文件成功保存后发生的操作。

Basic Backend Setup

javascript
import express from 'express';
import { initLocalStorageServer } from '@blocklet/uploader-server';
import Upload from '../models/upload'; // 你的数据库模型

const router = express.Router();

// 初始化上传器服务器中间件
const localStorageServer = initLocalStorageServer({
  // 上传文件将存储的目录
  path: process.env.UPLOAD_DIR,
  express,

  // 此回调在文件成功上传后执行
  onUploadFinish: async (req, res, uploadMetadata) => {
    const {
      id: filename, // 磁盘上唯一的随机文件名
      size,
      metadata: { filename: originalname, filetype: mimetype },
    } = uploadMetadata;

    // 为上传的文件构建公共 URL
    const fileUrl = new URL(process.env.APP_URL);
    fileUrl.pathname = `/uploads/${filename}`;

    // 将文件信息保存到你的数据库
    const doc = await Upload.insert({
      mimetype,
      originalname,
      filename,
      size,
      url: fileUrl.href,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
      createdBy: req.user.did,
    });

    // 以 JSON 响应形式返回数据库文档
    // 此数据将传递给前端的 onUploadFinish 回调
    return doc;
  },
});

// 将中间件挂载到 '/uploads' 路由上
// 确保任何必要的身份验证/授权中间件在其之前运行
router.use('/uploads', yourAuthMiddleware, localStorageServer.handle);

export default router;

配置选项

initLocalStorageServer 函数接受一个包含以下属性的选项对象:

选项类型必需描述
pathstring用于存储上传文件的目录的绝对路径。
expressFunctionExpress 应用程序实例。
onUploadFinishFunction一个 async 回调函数,在文件上传完成后运行。它接收 (req, res, uploadMetadata)。返回值将作为 JSON 响应发送到前端。
onUploadCreateFunction一个 async 回调函数,在新的上传启动但数据传输之前运行。可用于验证或授权检查。它接收 (req, res, uploadMetadata)
expiredUploadTimeNumber不完整上传被视为过期并由后台作业清理的时间(以毫秒为单位)。默认值: 1000 * 60 * 60 * 24 * 3 (3 天)。
...restPropsobject底层 @tus/server 包的任何其他有效选项都将被传递。

回调详解

onUploadFinish(req, res, uploadMetadata)

这是处理已完成上传的主要回调。它是将文件元数据保存到数据库、触发 Webhook 或执行其他上传后操作的理想位置。

uploadMetadata 对象

传递给回调的 uploadMetadata 对象包含有关已上传文件的详细信息:

属性类型描述
idstring服务器磁盘上唯一的、随机生成的文件名。
sizenumber文件的总大小(以字节为单位)。
offsetnumber当前已上传的字节数。在此回调中应等于 size
metadataobject包含客户端提供的元数据的对象。
metadata.filenamestring来自用户计算机的原始文件名。
metadata.filetypestring文件的 MIME 类型(例如 image/jpeg)。
runtimeobject包含有关文件位置的运行时信息的对象。
runtime.absolutePathstring文件在服务器文件系统上的完整路径。

返回值

你从 onUploadFinish 返回的值将被序列化为 JSON 并发送回前端 Uploader 组件。这允许你传回数据库记录 ID、公共 URL 或任何其他相关数据。

自动清理

该中间件会自动设置一个每小时运行的后台 cron 作业(auto-cleanup-expired-uploads)。此作业会安全地从存储目录中删除任何超过 expiredUploadTime 的部分或过期上传,防止服务器被不完整的文件填满。

高级功能

EXIF 数据移除

为了保护隐私和安全,中间件会在上传完成后自动尝试从上传的图像(.jpeg.tiff 等)中剥离 EXIF(可交换图像文件格式)元数据。

手动删除文件

返回的服务器实例包含一个 delete 方法,你可以用它以编程方式删除已上传的文件及其关联的元数据文件。

Manually Deleting a File

javascript
import { localStorageServer } from './setup'; // 假设你已导出该实例

async function deleteFile(filename) {
  try {
    await localStorageServer.delete(filename);
    console.log(`成功删除 ${filename}`);
  } catch (error) {
    console.error(`删除 ${filename} 失败:`, error);
  }
}

现在你已经知道如何处理直接上传,你可能希望让用户能够从外部服务导入文件。请继续下一节,了解 initCompanion

下一步:initCompanion(options)

了解如何设置 Companion 中间件,以允许用户从 Unsplash 和直接 URL 等远程来源导入文件。