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

> Compare SMMS, Aliyun OSS, and Qiniu built-in uploaders in PicList-Core. Learn about their multipart POST, signed PUT, and SDK-generated token differences.

- Repository: [Kuingsmile/piclist-core](https://github.com/kuingsmile/piclist-core)
- Tags: comparison
- Published: 2026-03-05

---

**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`](https://github.com/kuingsmile/piclist-core/blob/main/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`](https://github.com/kuingsmile/piclist-core/blob/main/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`](https://github.com/kuingsmile/piclist-core/blob/main/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

```typescript
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

```typescript
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

```typescript
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`](https://github.com/kuingsmile/piclist-core/blob/main/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`](https://github.com/kuingsmile/piclist-core/blob/main/smms.ts), [`aliyun.ts`](https://github.com/kuingsmile/piclist-core/blob/main/aliyun.ts), [`qiniu.ts`](https://github.com/kuingsmile/piclist-core/blob/main/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.