picgo-plugin-s3-uploader

March 31, 2026 · View on GitHub

一个面向 AWS S3、Garage、MinIO 等 S3 兼容对象存储的 PicGo 插件,支持文件上传、删除,以及输出 imgproxy 等插件使用的数据字段

它负责把文件上传到 S3 兼容服务,并输出:

  • 正常可访问的 url / imgUrl
  • picgo-plugin-imgproxy 使用的稳定 imgproxySource

功能概览

  • 支持 AWS S3 / Garage / MinIO 等 S3 兼容服务
  • 支持 PicGo GUI 删除文件时同步执行 S3 DELETE Object
  • 支持 uploadPath 上传路径模板
  • 支持 outputURLPattern 自定义输出 URL 模板
  • 常见图片、视频、音频、文档、压缩包、网页资源类型会自动写入合适的 Content-Type
  • 可选写入 Content-Disposition: inline,让浏览器更倾向于直接预览
  • 内置中英文文案,并优先跟随 PicGo / PicList 当前语言设置

安装

PicGo GUI / PicList

  • 可以直接在插件设置页安装 s3-uploader
  • 也可以安装完整包名 picgo-plugin-s3-uploader

PicGo Core

picgo install picgo-plugin-s3-uploader

配置项

Key说明示例
accessKeyIDS3 Access Key。YOUR_ACCESS_KEY
secretAccessKeyS3 Secret Key。YOUR_SECRET_KEY
bucketName目标 bucket 名称。public
uploadPath上传路径模板,可使用占位符。img/{year}/{month}/{md5}.{ext}
outputURLPattern自定义输出 URL 模板;为空时按默认规则推导公开 URL。https://cdn.example.com/{encodedKey}
region签名区域。AWS 常见为 us-east-1;Garage 为 garageus-east-1
endpointS3 API Endpoint。AWS S3 可留空。必须是完整的 http://https:// 地址。https://minio.example.com
pathStyleAccess是否使用 path-style 请求。Garage / MinIO 常见为 truetrue
rejectUnauthorized是否拒绝无效 TLS 证书。true
acl对象 ACL;若服务不支持可留空。public-read
contentDispositionInline是否在上传时写入 Content-Disposition: inlinefalse

配置示例

Garage

{
  "picBed": {
    "current": "s3-uploader",
    "uploader": "s3-uploader",
    "s3-uploader": {
      "accessKeyID": "YOUR_ACCESS_KEY",
      "secretAccessKey": "YOUR_SECRET_KEY",
      "bucketName": "public",
      "uploadPath": "img/{year}/{month}/{md5}.{ext}",
      "outputURLPattern": "https://{bucket}.example.com/{encodedKey}",
      "region": "garage",
      "endpoint": "https://garage-api.example.com",
      "pathStyleAccess": true,
      "rejectUnauthorized": true,
      "acl": "public-read",
      "contentDispositionInline": true
    }
  }
}

MinIO

{
  "picBed": {
    "current": "s3-uploader",
    "uploader": "s3-uploader",
    "s3-uploader": {
      "accessKeyID": "YOUR_ACCESS_KEY",
      "secretAccessKey": "YOUR_SECRET_KEY",
      "bucketName": "public",
      "uploadPath": "img/{year}/{month}/{fileName:/\\s+/g,'-'}.{extName}",
      "outputURLPattern": "https://cdn.example.com/{encodedKey}",
      "region": "us-east-1",
      "endpoint": "https://minio.example.com",
      "pathStyleAccess": true,
      "rejectUnauthorized": true,
      "acl": "public-read",
      "contentDispositionInline": true
    }
  }
}

AWS S3

{
  "picBed": {
    "current": "s3-uploader",
    "uploader": "s3-uploader",
    "s3-uploader": {
      "accessKeyID": "YOUR_ACCESS_KEY",
      "secretAccessKey": "YOUR_SECRET_KEY",
      "bucketName": "public",
      "uploadPath": "img/{year}/{month}/{uuidN}.{extName}",
      "outputURLPattern": "https://cdn.example.com/{encodedKey}",
      "region": "us-east-1",
      "pathStyleAccess": false,
      "rejectUnauthorized": true,
      "acl": "public-read",
      "contentDispositionInline": true
    }
  }
}

预览与下载

浏览器是“直接预览”还是“弹出下载”,主要取决于对象响应头:

  • Content-Type 是否正确,例如 video/mp4application/pdf
  • Content-Disposition 是否被设置为 attachmentinline

本插件默认不会强行写 Content-Disposition,而是优先依赖正确的 Content-Type。如果你希望浏览器更明确地按预览处理,可以开启 contentDispositionInline

模板语法

uploadPathoutputURLPattern 共用同一套模板语法。

通用占位符

以下占位符在 uploadPathoutputURLPattern 中都可使用。

分类占位符
时间{year} {month} {day} {hour} {minute} {second} {millisecond} {timestamp} {timestampMS}
文件{fullName} {fileName} {filename} {basename} {name} {extName} {ext}
哈希{crc32} {md5} {md5B64} {md5B64Short} {sha1} {sha256}
上传上下文{bucket} {region} {acl} {contentType} {mime} {size} {uuid} {uuidN}
Endpoint{endpoint} {endpointOrigin} {endpointProtocol} {endpointHost} {endpointHostname} {endpointPort} {endpointPath} {pathStyleAccess}

outputURLPattern 专属占位符

占位符说明
{url}插件按默认规则推导出的公开 URL
{origin} {protocol} {host} {hostname} {port}默认公开 URL 的主机信息
{pathname}默认公开 URL 的路径部分,带前导 /
{path}默认公开 URL 的路径部分,不带前导 /
{key} {objectKey} {uploadPath}对象 key,未编码
{encodedKey}URL 安全的对象 key
{dir}对象 key 的目录部分,未编码
{encodedDir}URL 安全的目录部分
{bucketPath}bucket/key
{encodedBucketPath}URL 安全的 bucket/key
{eTag} {etag}上传返回的 eTag

模板操作语法

下面用一组固定输入说明模板操作语法:

字段示例值
bucketpublic-bucket
md52095312189753de6ad47dfe20cbe97ec
fileNameEcho idle 01
fullNameEcho idle 01.png
写法输入结果说明
{bucket}bucket = public-bucketpublic-bucket直接取值
{md5:8}md5 = 2095312189753de6ad47dfe20cbe97ec20953121取前 8 位
{md5:0,8}md5 = 2095312189753de6ad47dfe20cbe97ec20953121从第 0 位开始取 8 位
{fileName:/\\s+/g,'-'}fileName = Echo idle 01Echo-idle-01把连续空格替换为 -
{fullName:/\\s+/g,'_'}fullName = Echo idle 01.pngEcho_idle_01.png把连续空格替换为 _
{fullName:/[^A-Za-z0-9._-]+/g,''}fullName = Echo idle 01.pngEchoidle01.png移除空格和其他不在白名单内的字符

说明:

  • {name:8} 等价于 {name:0,8}
  • 正则写法中的 flags 可省略
  • replacement 需要写在单引号里

常见模板示例

场景模板结果示例
按年月归档img/{year}/{month}/{fullName}img/2026/03/Echo idle 01.png
用 md5 作为文件名img/{year}/{month}/{md5}.{ext}img/2026/03/2095312189753de6ad47dfe20cbe97ec.png
把空格替换为 -img/{fileName:/\\s+/g,'-'}.{extName}img/Echo-idle-01.png
输出到 CDNhttps://cdn.example.com/{encodedKey}https://cdn.example.com/img/Echo-idle-01.png
bucket 作为子域名https://{bucket}.cdn.example.com/{encodedKey}https://public.cdn.example.com/img/Echo-idle-01.png

outputURLPattern 使用建议

如果你是在拼装最终公开 URL,优先使用:

推荐占位符原因
{encodedKey}对中文、空格和特殊字符更安全
{path} / {pathname}可以直接复用默认推导出的路径结构
{encodedBucketPath}适合自行拼接 bucket/key

endpoint 规则

项目说明
填写内容endpoint 填的是 S3 API 地址,不是 CDN 域名或公开访问域名
AWS S3可留空,插件会根据 region 自动推导
协议要求必须写完整的 http://https://
禁止内容不允许带 query / hash
域名分离场景如果公开访问域名和 API 地址不同,请把公开域名写到 outputURLPattern
自动归一化若误把 bucket 写进 endpoint 的 host 或 path,插件会自动去重

默认公开 URL 推导规则

outputURLPattern 为空时:

条件结果
endpoint 已设置,pathStyleAccess = truehttps://endpoint/bucket/key
endpoint 已设置,pathStyleAccess = falsehttps://bucket.endpoint/key
endpoint 未设置按 AWS 官方 S3 域名规则结合 region 自动推导

如果你的 API Endpoint、公开访问域名、CDN 域名不是同一个地址,建议显式配置 outputURLPattern

上传成功后写入的字段

这些字段可供其他插件继续消费,尤其是 picgo-plugin-imgproxy

字段说明示例
uploadPath对象 keyimg/Echo-idle-01.png
eTag上传返回的 eTagetag-value
imgproxySource.backend固定为 s3s3
imgproxySource.bucketbucket 名称public
imgproxySource.key对象 keyimg/Echo-idle-01.png

对应的 S3 来源统一为:

s3://bucket/key

删除支持

PicGo GUI 删除文件时,本插件会监听 remove 事件,并对当前插件上传的对象执行 S3 DELETE Object

行为说明
删除范围只处理 type === "s3-uploader" 的项目
key 来源优先使用 imgproxySource.key,没有时回退到 uploadPath
不存在对象记为“已不存在”,不视为硬错误
用户反馈会同时写日志,并在 GUI 中弹出通知

与 picgo-plugin-imgproxy 联用

当你同时安装:

  • picgo-plugin-s3-uploader
  • picgo-plugin-imgproxy

并在 picgo-plugin-imgproxy 中开启:

{
  "enableS3Source": true
}

imgproxy 插件会优先读取本插件写出的:

{
  "imgproxySource": {
    "backend": "s3",
    "bucket": "public",
    "key": "img/Echo-idle-01.png"
  }
}

并据此生成s3格式的链接进行处理:

/rs:fit:300:300/plain/s3://public/img/Echo-idle-01.png