SMMS vs Aliyun OSS vs Qiniu: How Built-in Uploaders Differ in PicList-Core

SMMS uses multipart/form-data POST requests with simple bearer tokens, Aliyun OSS performs direct PUT requests signed with HMAC-SHA1, and Qiniu transmits base64-encoded images via POST using SDK-generated upload tokens.

PicList-Core (kuingsmile/piclist-core) provides a unified image hosting workflow by abstracting diverse storage providers behind a common uploader interface. While all built-in uploaders register via ctx.helper.uploader.register, the implementations for SMMS, Aliyun OSS, and Qiniu differ fundamentally in transport protocols, authentication schemes, and payload encoding.

Upload Protocol and Authentication Architectures

Each uploader implements a distinct HTTP transport strategy tailored to its target service’s API contract.

SMMS: Multipart Form Data with Bearer Token

In src/plugins/uploader/smms.ts, the handle method constructs a multipart/form-data POST request to the SM.MS API endpoint (/api/v1/file/upload or /api/v2/upload). Authentication relies on a simple token passed in the Authorization header. This implementation uses only Node.js built-in modules, requiring no external SDKs or cryptographic libraries.

Aliyun OSS: Direct PUT with HMAC-SHA1 Signature

The Aliyun uploader in src/plugins/uploader/aliyun.ts performs a PUT request directly to a specified OSS bucket. Before transmission, it generates an HMAC-SHA1 signature from the accessKeySecret and request details to authenticate the operation. This uploader depends on the mime package for Content-Type detection and Node’s native crypto module for request signing.

Qiniu: Base64 Encoding with SDK Token Generation

Located in src/plugins/uploader/qiniu.ts, the Qiniu uploader sends a POST request to Qiniu’s putb64 API endpoint. Unlike the others, it encodes the image as base64 before inclusion in the request body. Authentication requires an upload token (UpToken) generated via the official qiniu SDK using qiniu.auth.digest.Mac and qiniu.rs.PutPolicy, making it the only built-in uploader with a mandatory external SDK dependency.

Configuration Schemas and Dependencies

The required configuration fields reflect each service’s security model:

  • SMMS: Requires only a token string, with an optional backupDomain for URL resolution. No external dependencies.
  • Aliyun OSS: Requires accessKeyId, accessKeySecret, bucket, and area, plus optional fields including path, webPath, customUrl, and options.
  • Qiniu: Requires accessKey, secretKey, bucket, url, and area, with optional options and path.

Response Handling and URL Construction

After a successful upload, each uploader constructs the final image URL using service-specific logic:

  • SMMS: Parses the JSON response to extract body.data.url.
  • Aliyun OSS: Constructs the URL by combining the bucket domain (or customUrl if provided) with the encoded object path.
  • Qiniu: Concatenates the configured base url with the key returned by the API.

All three emit notification events on non-200 HTTP status codes, though Qiniu specifically logs the API-returned error message for debugging.

Practical Usage Examples

Configuring and Using SMMS

import PicGo from 'picgo'

PicGo.setConfig('picBed.smms', { token: 'YOUR_SMMS_TOKEN' })

await PicGo.upload({
  fileName: 'screenshot.png',
  buffer: await fs.promises.readFile('screenshot.png')
})

console.log(PicGo.output[0].imgUrl)

Configuring and Using Aliyun OSS

PicGo.setConfig('picBed.aliyun', {
  accessKeyId: 'AKID',
  accessKeySecret: 'SECRET',
  bucket: 'my-bucket',
  area: 'cn-hangzhou',
  path: 'images/',
  customUrl: 'https://cdn.example.com'
})

await PicGo.upload({
  fileName: 'photo.jpg',
  buffer: imageBuffer
})

Configuring and Using Qiniu

PicGo.setConfig('picBed.qiniu', {
  accessKey: 'AK',
  secretKey: 'SK',
  bucket: 'my-qiniu',
  url: 'https://my-cdn.com',
  area: 'z0'
})

await PicGo.upload({
  fileName: 'animation.gif',
  base64Image: (await fs.promises.readFile('animation.gif')).toString('base64')
})

Summary

  • SMMS offers zero-dependency simplicity via HTTP multipart uploads and minimal configuration, ideal for quick integrations.
  • Aliyun OSS provides direct bucket PUT operations with custom HMAC-SHA1 signing, suitable for high-throughput scenarios without SDK overhead.
  • Qiniu leverages base64 encoding and official SDK token generation, supporting specific CDN optimizations while requiring external dependencies.

Frequently Asked Questions

Which PicList-Core uploader requires the fewest dependencies?

SMMS requires no external SDKs or libraries, using only Node.js built-in modules. Aliyun OSS requires mime and crypto, while Qiniu depends on the official qiniu SDK for token generation.

Can I use custom domains with these uploaders?

Yes. Aliyun OSS supports customUrl and webPath configuration options to override the default bucket domain. Qiniu uses the url field for custom CDN endpoints. SMMS offers a backupDomain option for URL resolution when the primary domain is unavailable.

Why does Qiniu use base64 encoding instead of raw buffers?

According to the implementation in src/plugins/uploader/qiniu.ts, the uploader targets Qiniu’s putb64 API endpoint, which accepts base64-encoded images directly in the POST body. This approach eliminates multipart form boundaries and aligns with Qiniu’s direct upload workflows designed for browser-to-CDN transmission.

How does PicList-Core unify these different upload methods?

All three uploaders register via ctx.helper.uploader.register in their respective files (smms.ts, aliyun.ts, qiniu.ts), exposing a standardized handle function and config schema. This registration pattern allows the core application to treat SMMS, Aliyun OSS, and Qiniu interchangeably while preserving their service-specific transport and authentication logic.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →