# 上传时自动检测 MIME
Source: https://bitiful-docs.mintlify.app/best-practice/auto-detect-mime
本文介绍如何用缤纷云对文件 MIME 的自动检测能力。
## 利用缤纷云 S4 自动检测文件对象的 MIME
24 年,我们强化了 **M2TS** 和 **M4S** 视频切片类型的检测,以帮助您应对日渐严重的 **资源滥用攻击**。
在 《[在客户端中安全地上传文件](/best-practice/web-uploads)》的最佳实践中,我们的末尾的 Js 脚本片段将 Content-Type 强制置空完全是刻意为之,因为:
* axios 采用 PUT 请求时会默认带上 `application/x-www-form-urlencoded` 的 `Content-Type`,而这与 S3 PUT 中对 `Content-Type` 的预期不同;
* 对于 S3 协议来说,上传时主动带上文件 MIME 并赋值给 `Content-Type` 可作为元数据同时保存至 S3 后端系统当中(告诉 S3 上传的对象是何种 MIME 类型)
所以最好的做法可能是 ———— 将 `Content-Type` 指定为上传文件的 MIME 类型,例如:
```Javascript theme={null}
const config = {
headers: {
'Content-Type': 'image/jpeg',
},
};
```
那么在 AWS / OSS 中最好的做法可能是:用 Javascript 程序创建有效的文件类型判断,并在请求「预签名链接」时告知服务端我们需要上传一个何种 MIME 类型的文件:
```Javascript theme={null}
const url = `/s3_upload_url`;
const params = {key: '1.jpg', mime: 'image/jpeg'};
```
在 Bitiful S4 中,我们有 **更好的** 选择:
**`Bitiful S4 在接收到 Content-Type 为空的上传请求时,会自动根据后缀与字节智能地判断文件的 MIME 类型。`**
> AWS S3 和 OSS 中会全部变成 "application/octet-stream"
这与 Javascript 中 file.type 只依赖后缀名的判断不同,把 MIME 推测工作交给 S4 会更可靠和真实。
而你需要做的一切就是:
1. **删除你的 MIME 判断代码**
2. **发起 Put 请求时将 Content-Type 置为 Null**
# 使用 Bitifs 将缤纷云 S4 挂载到本地
Source: https://bitiful-docs.mintlify.app/best-practice/solutions/bitifs
## 目标
Bitifs BETA 是缤纷云官方推出的 S4 对象存储挂载工具,可以在 Windows、macOS 和 Linux 上利用它将对象存储映射成本地文件夹。
**本指南介绍如何设置 BitiFS 以将您 S4 挂载到本地。**
请确保您已 [注册缤纷云账号](https://console.bitiful.com/) 并完成 [实名认证](https://console.bitiful.com/users)。
## 前置条件
* 已经 [创建](/bitiful-s4/handbook/quick-start) S4 存储桶
* 创建了子账户,并创建 access\_key
* 确保为 `子账户` 赋予了 `相应存储桶` 所有权限
## 分系统设置说明
请注意:Windows 需要提前安装 FUSE 支持 [Winfsp](https://github.com/billziss-gh/winfsp/releases)
#### 下载
AMD64: [https://tools.bitiful.com/bitifs/bitifs.exe](https://tools.bitiful.com/bitifs/bitifs.exe)
#### 安装使用
#### CMD 设置 AK/SK:
```
set AWS_ACCESS_KEY_ID={ak}
set AWS_SECRET_ACCESS_KEY={sk}
```
#### Powershell 设置 AK/SK:
```
$env:AWS_ACCESS_KEY_ID={ak}
$env:AWS_SECRET_ACCESS_KEY={sk}
```
然后执行:`./bitifs.exe bucketname B:` 挂载
请注意:macOS 需要提前安装 FUSE 支持 [macFUSE](https://github.com/macfuse/macfuse/releases)
#### 下载
Intel 芯片: [https://tools.bitiful.com/bitifs/bitifs\_macos\_amd64](https://tools.bitiful.com/bitifs/bitifs_macos_amd64)
Apple 芯片: [https://tools.bitiful.com/bitifs/bitifs\_macos\_arm64](https://tools.bitiful.com/bitifs/bitifs_macos_arm64)
#### 设置 AK/SK:
```
export AWS_ACCESS_KEY_ID={ak}
export AWS_SECRET_ACCESS_KEY={sk}
```
然后执行:`mkdir -p ~/bitiful-mount && ./bitifs bitifsmount ~/bitiful-mount` 挂载
#### 下载
AMD64: [https://tools.bitiful.com/bitifs/bitifs\_linux\_amd64](https://tools.bitiful.com/bitifs/bitifs_linux_amd64)
ARM64: [https://tools.bitiful.com/bitifs/bitifs\_linux\_arm64](https://tools.bitiful.com/bitifs/bitifs_linux_arm64)
#### 设置 AK/SK:
```
export AWS_ACCESS_KEY_ID={ak}
export AWS_SECRET_ACCESS_KEY={sk}
```
然后执行:`mkdir -p ~/bitiful-mount && ./bitifs bitifsmount ~/bitiful-mount` 挂载
热心网友制作的 Linux 一键脚本:[https://gitee.com/cncsrf/bitiful-oss](https://gitee.com/cncsrf/bitiful-oss)
# 将 S4 对象存储与 Rclone 结合使用
Source: https://bitiful-docs.mintlify.app/best-practice/solutions/rclone
了解如何设置 Rclone 以将您的文件与 S4 对象存储同步。
## 目标
Rclone 是一种备份工具,可以与各种存储后端同步,并且可以在 Windows、macOS 和 Linux 上使用。
**本指南介绍如何设置 Rclone 以将您的文件与 S4 对象存储同步。**
请确保您已 [注册缤纷云账号](https://console.bitiful.com/) 并完成 [实名认证](https://console.bitiful.com/users)。
## 前置条件
* 已经 [创建](/bitiful-s4/handbook/quick-start) S4 存储桶
* 创建了子账户,并创建 access\_key
* 确保为 `子账户` 赋予了 `相应存储桶` 所有权限
## 说明
要配置 Rclone,请编辑或创建 `~/.config/rclone/rclone.conf` 文件并添加以下内容:
```bash theme={null}
[s4-demo]
type = s3
provider = Other
env_auth = false
access_key_id =
secret_access_key =
end = https://s3.bitiful.net
```
Rclone 现在可以使用了。
**命令示例**
列出所有 bucket:
```bash theme={null}
$ rclone lsd s4-demo:
```
创建新 bucket:
```bash theme={null}
$ rclone mkdir s4-demo:mybucket
```
列出 bucket 的内容:
```bash theme={null}
$ rclone ls s4-demo:mybucket
```
将 `/home/user/documents` 同步到 bucket:
```bash theme={null}
$ rclone sync /home/user/documents s4-demo:我的桶
```
将文件 `/home/user/bitifl-logo.png` 复制到存储桶中:
```bash theme={null}
$ rclone copy /home/user/bitifl-logo.png s4-demo:mybucket
```
从存储桶下载文件 `bitifl-logo.png`:
```bash theme={null}
$ rclone copy s4-demo:mybucket/bitifl-logo.png bitifl-logo.png
```
将存储桶挂载成 `本地目录`:
```bash theme={null}
$ rclone mount s4-demo:/ /LOCAL_DIR --no-modtime --no-checksum --no-seek \
--daemon \
--allow-other \
--vfs-cache-mode full \
--dir-cache-time 1m \
--buffer-size 128M \
--transfers 200 \
--checkers 200 \
--tpslimit 200 \
--vfs-read-chunk-size 10M \
--vfs-read-chunk-size-limit 256M \
--vfs-cache-max-age 24h \
--vfs-cache-max-size 1G \
--log-level INFO \
--log-file ./rclone.log \
--umask 002 \
--attr-timeout 1s \
--volname "s4mount"
```
#### 相关阅读
1. [官方 Rclone 文档](https://rclone.org/docs/)。
2. [Ugediao: Debian 服务器通过 rclone 挂载缤纷云](https://ugediao.com/debian-rclone-bitiful.html)
# CDN 使用高级防盗链
Source: https://bitiful-docs.mintlify.app/best-practice/token-link
本文介绍如何在缤纷云 CDN 中使用高级防盗链。
为保护资源被滥用,CDN 配置 Referer 和 IP 的黑白名单来判断是否是合法用户及来源。然后 Referer 可被 **轻松伪造**,实际使用中仍存在隐患。
为了更好地保护源站资源,CDN 支持加密 URL 的功能,可以通过 **高级鉴权** 的方式来正确响应合法请求、拒绝非法请求。
## 工作原理
在控制台为需要保护的 “加速项目” 启用“高级鉴权”,并设置一个名为 `鉴权 Key` 的“暗号”,利用与 CDN 同样策略的方式向合法用户提供利加密的 URL,并通过 ts 参数设定该 URL 的有效时间戳;
用户在访问资源时会根据下面的 `规则` 判断请求的合法性:
* **是** - `继续判断下一条规则`
* **否** - `返回 403 Forbidden`;
* **是** - `继续判断下一条规则`
* **否** - `返回 403 Forbidden`;
* **是** - `200 并返回资源`
* **否** - `返回 403 Forbidden`。
## 典型范例
一个正确的典型高级防盗链 URL 应该类似于:
> [http://tests3origin.dogecast.com/image.jpg?`_ts`=1701091625&`_btf_tk`=960edecad993db64d8aab938c7dfc3f7](http://tests3origin.dogecast.com/image.jpg?_ts=1701091625&_btf_tk=960edecad993db64d8aab938c7dfc3f7)
其中:
* ts: 为 UTC 时间戳,意为:该 URL 的时效时间(**晚于该时间** 后链接将返回 403)
* token: 用 **tokenKey** + **path** (本例为 /image.jpg) + **args** (本例为 \_ts=1701091625)
## 代码示例:
下面是部分主流语言实现上述 **典型范例** 中的 `高级鉴权 URL` 的示例代码。
它们应该可在各个 playground 中被正确执行。
**安全提示:**
下面虽然列出了部分客户端语言的示例,但缤纷云建议您永远 **只在服务端生成** 高级鉴权链接并分发给客户端。
因为这可以:
1. 最大程度保护 **tokenKey** 的安全;
2. 更高效、安全地随时替换 **tokenKey**(不必迫使用户更新客户端)。
### PHP 语言版本
```php theme={null}
function creatLink() {
$deadLine = time() + 60; # 链接在未来的 60秒 内有效
$tokenKey = "**testsecretkey**"; # 缤纷云后台设置的 鉴权Key
$domain = "http://tests3origin.dogecast.com";
$fileName = "/image.jpg";
$md5RawString = $tokenKey.$fileName.$deadLine;
$md5Result = md5($md5RawString);
$tokenLink = $domain.$fileName.
"?_btf_tk=".$md5Result.
"&_ts=".$deadLine;
return $tokenLink;
}
echo creatLink();
```
### Go 语言版本
time.Now().Unix() 有效性提示
* 大部分 Golang playground 并不支持获取时间戳 ———— time.Now().Unix() 将会得到一个错误的早期时间;
* 请注意选择部分第三方支持该特性的 Golang playground;
* 以下 golang 示例代码可以在 [Programiz](https://www.programiz.com/golang/online-compiler/) 得到正确地执行。
```go theme={null}
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"time"
)
func createLink() string {
deadLine := time.Now().Unix() + 60 // 链接在未来的 60秒 内有效
tokenKey := "testsecretkey" // 缤纷云后台设置的 鉴权Key
domain := "http://tests3origin.dogecast.com"
fileName := "/image.jpg"
rawString := fmt.Sprintf("%s%s%d", tokenKey, fileName, deadLine)
hasher := md5.New()
hasher.Write([]byte(rawString))
md5Result := hex.EncodeToString(hasher.Sum(nil))
tokenLink := fmt.Sprintf("%s%s?_btf_tk=%s&_ts=%d", domain, fileName, md5Result, deadLine)
return tokenLink
}
func main() {
fmt.Println(createLink())
}
```
### Python3 语言版本
```python theme={null}
import hashlib
import time
def create_link():
deadLine = int(time.time()) + 60 # 链接在未来的 60秒 内有效
tokenKey = "testsecretkey" # 缤纷云后台设置的 鉴权Key
domain = "http://tests3origin.dogecast.com"
fileName = "/image.jpg"
rawString = f"{tokenKey}{fileName}{deadLine}"
md5Result = hashlib.md5(rawString.encode()).hexdigest()
tokenLink = f"{domain}{fileName}?_btf_tk={md5Result}&_ts={deadLine}"
return tokenLink
print(create_link())
```
### JS 语言版本
```javascript theme={null}
const crypto = require('crypto');
function createLink() {
let deadLine = Math.floor(Date.now() / 1000) + 60; // 链接在未来的 60秒 内有效
let tokenKey = "testsecretkey"; // 缤纷云后台设置的 鉴权Key
let domain = "http://tests3origin.dogecast.com";
let fileName = "/image.jpg";
let rawString = tokenKey + fileName + deadLine;
let md5Result = crypto.createHash('md5').update(rawString).digest('hex');
let tokenLink = domain + fileName + "?_btf_tk=" + md5Result + "&_ts=" + deadLine;
return tokenLink;
}
console.log(createLink());
```
### Java 语言版本
```Java theme={null}
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;
import java.math.BigInteger;
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException {
System.out.println(createLink());
}
public static String createLink() throws NoSuchAlgorithmException {
long deadline = Instant.now().getEpochSecond() + 60; // 链接在未来的 60秒 内有效
String tokenKey = "testsecretkey"; // 缤纷云后台设置的 鉴权Key
String domain = "http://tests3origin.dogecast.com";
String fileName = "/image.jpg";
String rawString = tokenKey + fileName + deadline;
String md5Result = getMd5(rawString);
String tokenLink = domain + fileName + "?_btf_tk=" + md5Result + "&_ts=" + deadline;
return tokenLink;
}
public static String getMd5(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageDigest = md.digest(input.getBytes(StandardCharsets.UTF_8));
BigInteger no = new BigInteger(1, messageDigest);
String hashtext = no.toString(16);
while (hashtext.length() < 32) {
hashtext = "0" + hashtext;
}
return hashtext;
}
catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
```
### rust 语言版本
```rust theme={null}
extern crate chrono;
extern crate crypto;
use chrono::prelude::*;
use crypto::digest::Digest;
use crypto::md5::Md5;
fn create_link() -> String {
let deadline = Utc::now().timestamp() + 60; // 链接在未来的 60秒 内有效
let token_key = "testsecretkey"; // 缤纷云后台设置的 鉴权Key
let domain = "http://tests3origin.dogecast.com";
let file_name = "/image.jpg";
let raw_string = format!("{}{}{}", token_key, file_name, deadline);
let mut hasher = Md5::new();
hasher.input_str(&raw_string);
let md5_result = hasher.result_str();
let token_link = format!("{}{}?_btf_tk={}&_ts={}", domain, file_name, md5_result, deadline);
token_link
}
fn main() {
println!("{}", create_link());
}
```
**请注意: 在运行 Rust 代码前需要在你的 Cargo.toml 文件中添加以下依赖**
```toml theme={null}
[dependencies]
chrono = "0.4"
rust-crypto = "0.2"
```
### swift 语言版本
```swift theme={null}
import CommonCrypto
import Foundation
func MD5(string: String) -> String {
let length = Int(CC_MD5_DIGEST_LENGTH)
var digest = [UInt8](repeating: 0, count: length)
if let data = string.data(using: String.Encoding.utf8) {
data.withUnsafeBytes { _ = CC_MD5($0.baseAddress, CC_LONG(data.count), &digest) }
}
return digest.map { String(format: "%02x", $0) }.joined()
}
func createLink() -> String {
let deadline = Int(Date().timeIntervalSince1970) + 60
let tokenKey = "testsecretkey"
let domain = "http://tests3origin.dogecast.com"
let fileName = "/image.jpg"
let rawString = "\(tokenKey)\(fileName)\(deadline)"
let md5Result = MD5(string: rawString)
let tokenLink = "\(domain)\(fileName)?_btf_tk=\(md5Result)&_ts=\(deadline)"
return tokenLink
}
print(createLink())
```
### kotlin 语言版本
```kotlin theme={null}
import java.security.MessageDigest
import java.time.Instant
fun createLink(): String {
val deadline = Instant.now().epochSecond + 60
val tokenKey = "testsecretkey"
val domain = "http://tests3origin.dogecast.com"
val fileName = "/image.jpg"
val rawString = "$tokenKey$fileName$deadline"
val md = MessageDigest.getInstance("MD5")
md.update(rawString.toByteArray())
val md5Result = md.digest().joinToString("") { "%02x".format(it) }
val tokenLink = "$domain$fileName?_btf_tk=$md5Result&_ts=$deadline"
return tokenLink
}
fun main() {
println(createLink())
}
```
# 在客户端中安全地上传文件
Source: https://bitiful-docs.mintlify.app/best-practice/web-uploads
本文介绍如何用预签名 URL 安全地让客户端端具备高性能的大文件上传能力。
## 为何不建议直接用 Javascript SDK 等客户端 SDK 来上传文件?
1. 容易被反编译后暴露 ak / sk
2. 不够灵活
安全建议:永远不要使用 API 下发 ak / sk
## 更好的方案
### 后端生成「预签名链接」并通过 API 下发
前端可以对预签名链接直接发起 PUT 请求,这样我们可以收获的好处有:
1. 更安全:永远不会因 `暴露客户端代码` 或 `被反编译` 而泄露至关重要的 AccessKey 和 SecretKey;
2. 更灵活:利用显式指定 `Content-Type` 和 `Content-Length` 来防止客户端被破解,从而绕过业务策略的限制
3. 低成本:统一由服务端传递预签名链接,客户端开发人员只需要完成 PUT HTTP 请求即可,不需要学习和调试不同语言下的 S3 SDK(事实证明,AWS SDK不同的语言版本由不同的团队维护,其规范、特性差异较大,不利于项目稳定。)
4. 高性能:上传请求依然是直接对 缤纷云 S4 发起,不需要服务端中转。
### 如何运作
让后端程序(golang、python、php、nodejs)调用相应的 SDK 生成一个具有 PutObject 方法效力的「预签名」链接传递给 Web 页面的 Javascript 脚本。
Javascript 脚本利用 网络请求组件(如 axios)来将本地文件 PUT 到上面提到的「预签名 PutObject 链接」
缤纷云开源了全功能预签名 API 本地部署项目。它无状态,可以作为微服务快速结合到当前的系统中。
Github: [https://github.com/bitiful/s3-presigned-api-server](https://github.com/bitiful/s3-presigned-api-server)
### 不同语言后端接口生成 PutObject 预签名链接示例:
```python main.py theme={null}
import boto3
from flask import Flask
from flask import render_template_string
from flask import request
app = Flask(__name__)
@app.get('/s3_upload_url')
def get_upload_url():
# Config
s3endpoint = 'https://s3.bitiful.net' # 请填入控制台 “Bucket 设置” 页面底部的 “Endpoint” 标签中的信息
s3region = 'cn-east-1'
s3accessKeyId = '<--子账户 accessKey-->' # 请到控制台创建子账户,并为子账户创建相应 accessKey
s3SecretKeyId = '<--子账户 secretKey-->' # !!切记,创建子账户时,需要手动为其分配具体权限!!
# 连接 S3
client = boto3.client(
's3',
aws_access_key_id = s3accessKeyId,
aws_secret_access_key = s3SecretKeyId,
endpoint_url = s3endpoint,
region_name = s3region
)
url = client.generate_presigned_url(
'put_object',
Params={
'Bucket': '<--缤纷云存储桶名-->',
'Key': request.args.get('key'),
},
ExpiresIn=3600
)
return {'url': url}
```
```javascript main.js theme={null}
// 参考 1:https://juejin.cn/post/7019216042220077092
// 参考 2:https://northflank.com/guides/connect-nodejs-to-minio-with-tls-using-aws-s3
const {
S3Client
} = require("@aws-sdk/client-s3");
const s3Client = new S3Client({
endpoint: "https://s3.bitiful.net",
credentials: {
accessKeyId: "<--子账户 accessKey-->",
secretAccessKey: "<--子账户 secretKey-->",
}
});
//引入相关模块
const {
PutObjectCommand,
} = require("@aws-sdk/client-s3");
const { getSignedUrl } = require("@aws-sdk/s3-request-presigner");
app.get("/s3_upload_url", (req, res, next) => {
//初始化命令实体
const putCmd = new PutObjectCommand({
Bucket: "<--缤纷云存储桶名-->",
Key: req.query.key
});
//获取签名
getSignedUrl(s3Client, putCmd, { expiresIn: 3600 }).then((url) => {
//将签名好的url回传给前台
res.send(url);
next();
});
});
```
```rust main.rs theme={null}
// 参考:https://developer.qiniu.com/kodo/12572/aws-sdk-rust-examples
// [dependencies]
// actix-web = "4"
// serde = { version = "1.0", features = ["derive"] }
// serde_json = "1.0"
// anyhow = "1.0.75"
// aws-config = "1.3.0"
// aws-credential-types = { version = "1.2.0", features = ["hardcoded-credentials"] }
// aws-sdk-s3 = "1.25.0"
// aws-sdk-sts = "1.22.0"
// aws-smithy-types = { version = "1.1.8", features = ["rt-tokio"] }
// tokio = { version = "1.32.0", features = ["full"] }
use actix_web::{web, App, HttpResponse, HttpServer, Responder};
use aws_config::{BehaviorVersion, SdkConfig};
use aws_credential_types::{provider::SharedCredentialsProvider, Credentials};
use aws_sdk_s3::{config::Region, presigning::PresigningConfig, Client};
use std::time::Duration;
async fn get_upload_url(query: web::Query) -> impl Responder {
let key = query.get("key").and_then(|v| v.as_str()).unwrap_or("");
let url = get_url(key);
let response_data = serde_json::json!({ "url": url.await.unwrap_or("".to_string())});
HttpResponse::Ok()
.content_type("application/json") // 设置响应的 Content-Type
.json(response_data)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/s3_upload_url", web::get().to(get_upload_url))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
async fn get_url(key: &str) -> anyhow::Result {
let client = Client::new(
&SdkConfig::builder()
.region(Region::new("cn-east-1"))
.endpoint_url("https://s3.bitiful.net")
.behavior_version(BehaviorVersion::v2023_11_09())
.credentials_provider(SharedCredentialsProvider::new(Credentials::from_keys(
"<--子账户 accessKey-->",
"<--子账户 secretKey-->",
None,
)))
.build(),
);
let request = client
.put_object()
.bucket("<--缤纷云存储桶名-->")
.key(key)
.presigned(
PresigningConfig::builder()
.expires_in(Duration::from_secs(36000))
.build()?,
)
.await?;
Ok(request.uri().to_string())
}
```
```go main.go theme={null}
// go get github.com/aws/aws-sdk-go
package main
import (
"encoding/json"
"log"
"net/http"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
const (
bucket = "<--缤纷云存储桶名-->"
endpoint = "https://s3.bitiful.net"
region = "cn-east-1"
accessKey = "<--子账户 accessKey-->"
secretKey = "<--子账户 secretKey-->"
)
func main() {
http.HandleFunc("/s3_upload_url", handleS3UploadURL)
log.Println("Server started at http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func handleS3UploadURL(w http.ResponseWriter, r *http.Request) {
// Parse query parameter
keys, ok := r.URL.Query()["key"]
if !ok || len(keys[0]) < 1 {
http.Error(w, "Missing 'key' query parameter", http.StatusBadRequest)
return
}
key := keys[0]
// Create AWS session
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String(region),
Endpoint: aws.String(endpoint),
Credentials: credentials.NewStaticCredentials(accessKey, secretKey, ""),
}))
// Create S3 service client
svc := s3.New(sess)
// Generate the URL
req, _ := svc.PutObjectRequest(&s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
urlStr, err := req.Presign(15 * time.Minute) // URL expires in 15 minutes
if err != nil {
http.Error(w, "Failed to sign request: "+err.Error(), http.StatusInternalServerError)
return
}
// Create JSON response
response := struct {
URL string `json:"url"`
}{
URL: urlStr,
}
jsonResponse, err := json.Marshal(response)
if err != nil {
http.Error(w, "JSON encoding error: "+err.Error(), http.StatusInternalServerError)
return
}
// Set Content-Type and write the response
w.Header().Set("Content-Type", "application/json")
w.Write(jsonResponse)
}
```
```php main.php theme={null}
# composer require aws/aws-sdk-php
require 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
// 配置
$bucket = '<--缤纷云存储桶名-->';
$region = 'cn-east-1';
$keyId = '<--子账户 accessKey-->';
$secret = '<--子账户 secretKey-->';
$endpoint = 'https://s3.bitiful.net';
// 创建 S3 客户端
$s3Client = new S3Client([
'version' => 'latest',
'region' => $region,
'credentials' => [
'key' => $keyId,
'secret' => $secret,
],
'endpoint' => $endpoint,
'use_path_style_endpoint' => true,
]);
// 检查是否有 key 参数
if (!isset($_GET['key']) || empty($_GET['key'])) {
header('Content-Type: application/json');
echo json_encode(['error' => 'Missing key parameter']);
http_response_code(400);
exit;
}
$key = $_GET['key'];
// 生成预签名 URL
try {
$cmd = $s3Client->getCommand('PutObject', [
'Bucket' => $bucket,
'Key' => $key
]);
$request = $s3Client->createPresignedRequest($cmd, '+20 minutes');
// 获取预签名 URL
$presignedUrl = (string) $request->getUri();
header('Content-Type: application/json');
echo json_encode(['url' => $presignedUrl]);
} catch (AwsException $e) {
header('Content-Type: application/json');
echo json_encode(['error' => $e->getMessage()]);
http_response_code(500);
}
```
### 前端上传示例:
```html upload_demo.web.html theme={null}
S3 File Upload
S3 File Upload
```
上面的 Javascript 脚本在发起 Put 请求时将「Content-Type」设置为空值,建议使用缤纷云独有的 [MIME 自动检测](/best-practice/auto-detect-mime) 功能。
# 主要名词与概念
Source: https://bitiful-docs.mintlify.app/bitiful-s4/definitions
这里列出和定义一些S4对象存储服务中遇到的概念。
缤纷云 S4 的存储桶均为 **目录桶**,约相当于 Amazon AWS 最新推出的:[Directory Buckets](https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/directory-buckets-overview.html)。
> AWS 基于它构建了最新的高性能 S3 产品:[S3 Express One Zone](https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/s3-express-one-zone.html)
## 存储桶(Bucket)
* 存储桶是您存储内容对象(Object)的独享空间,所有的对象都必须隶属于某个存储桶。存储桶具有各种配置属性,包括地域、访问权限等。
* 存储桶的名字全局唯一,如果您创建了某个名称的存储桶,其他用户将无法再创建同名的存储桶。
* 每一个桶的存储空间没有限制。
* 存储桶命名规范如下:
* 只能包括小写字母 a \~ z、数字 0 \~ 9 和 半角横线(-)。
* 开头和结尾只能是数字或字母。
* 长度必须在 4 \~ 63 个字符之间。
## 对象(Object)
对象是 S4 存储数据的基本单元,在本文档中 对象、文件 与 Object 意义相同。对象由键(Key),数据(Data)和元数据(Metadata)三部分组成。
* Key:为在某个存储桶(Bucket)中一个对象(文件)的唯一标识,它包含目录、后缀的完整路径。存储桶名 + Key 组成该对象在互联网上访问与操作的 [URL](https://baike.baidu.com/item/%E7%BB%9F%E4%B8%80%E8%B5%84%E6%BA%90%E5%AE%9A%E4%BD%8D%E7%B3%BB%E7%BB%9F);
* Data:为该数据的实体内容,例如:一张图片中;
* Metadata:与本地文件系统不同,对象存储独有可描述一个对象(文件)其他属性的“元数据”。
* 对象的命名规范如下:
* 使用 UTF-8 编码。
* 长度必须在 1~696 个字符之间。
* 不能以反斜线(\)开头。
* 不支持 \a、\b、\t、\n、\v、\f、\r 字符。
* 不支持 ASCII 0 \~ 31 和 127 的不可见字符
* 目录对象 vs 文件对象
* S4 特有对象类型,旨在为高性能场景带来原生的 Rename 等特性;
* 目录对象只能以斜杠(/)结尾;
* 目录对象没有实质的 Data 二进制数据(Body 为空);
- **存储桶(Bucket)名为**:somebucket;
- **Key 为**:userFiles/000001.avatar;
- **数据(Data)为**:该图片实际的二进制内容;
- **元数据(Metadata)为**:image/jpeg。在对象存储中,不需要依靠[文件扩展名](https://baike.baidu.com/item/%E6%96%87%E4%BB%B6%E6%89%A9%E5%B1%95%E5%90%8D/1270230)来判断文件类型(MIME),只要元数据(Metadata)中指定了其类型为“image/jpeg”,那么在访问时浏览器可自动识别为图片。
## 地域(Region)
地域表示 S4 的数据中心所在可用区的地理位置,目前只有中国东部1可用区(cn-east-1)。
## 子账户(Sub-user)
子账户是缤纷云最小的权限管理单位,每个子账户可以单独设置不同`存储桶`的权限,每个子账户下的 AccessKey 集成该子账户所有的权限。
## 访问密钥(AccessKey)
AccessKey 简称AK,是 AccessKey Id 和 AccessKey Secret 的统称,凭借 AccessKey,您可以在任何兼容 S3 协议的第三方工具、SDK 中方便地使用 缤纷云 S4。
# 图像 BlurHash 与 ThumbHash 哈希占位技术:
Source: https://bitiful-docs.mintlify.app/bitiful-s4/features/hash-placeholder
BlurHash 和 ThumbHash 为图像提供惊艳又轻量的预加载效果,让图片访问体验更上三层楼!
传统的图像加载方式往往会导致用户等待或看到空白页面。BlurHash 和 ThumbHash 通过轻量级哈希值预先生成模糊占位图,为用户提供即时反馈,大幅提升加载体验。
缤纷云 **CoreIX 原生支持** 获取 [BlurHash](https://blurha.sh/) 和 [ThumbHash](https://evanw.github.io/thumbhash/) 两种图像占位哈希技术,通过 [fmt=blurhash](/coreix/features/fmt) 或 [fmt=thumbhash](/coreix/features/fmt) 参数即可获取。
## 图像预加载占位方案对比
| **特性** | **高斯模糊图** | **BlurHash** | **ThumbHash** | **主色值** |
| :----- | :--------------------------- | :-------------------------- | :--------------------------- | :-------------------------- |
| 占数据库容量 | 较大 ( 200 \~ 5k 字节) | 极小 (30+ 字节) | 极小 (20+ 字节) | 最短 (7-9 字符) |
| 模糊质量 | 最高 | 较高 | 很高 | 无任何细节 |
| 性能影响 | 数据库性能影响较大 | 极小 | 极小 | 极小 |
| 综合评价 | 模糊质量最好
存储容量很大
效率一般 | 模糊质量较好
存储容量小
效率很高 | 模糊质量很好
存储容量更小
效率很高 | 纯色无细节
存储容量最小
效率最高 |
我们非常感谢 [BlurHash](https://evanw.github.io/thumbhash/) 和 [ThumbHash](https://blurha.sh/) 的开源,但原始库对图片格式支持 **非常有限**,更无法简单支持 **视频**、**动图**。得益于缤纷云 CoreIX 绝佳的 **视频**、**图片格式** 和 **色彩模式** 兼容能力,你可以简单我们的接口在 0.1 秒内获得大量的 **额外兼容性**,包括:
1. P3、Adobergb、CMYK 等色域或色彩模式的照片;
2. 大量 RAW 格式原片;
3. 借助 [frame 截图参数](/coreix/features/frame) 支持获取 `视频` 和 `动图` 的哈希占位图
## 方案预览
BlurHash 示例:左侧为原图,右侧为其 BlurHash 生成的模糊占位图
## 如何使用
### 原理与步骤
1. 只需在图像URL后添加相应参数:
* BlurHash: `fmt=blurhash`
* ThumbHash: `fmt=thumbhash`
2. 将得到的 `占位哈希值` 直接存入数据库
3. 在客户端请求数据时,直接将 `占位哈希值` 输出到接口结果(例如 json)中
4. 客户端根据接口中相关字段提供的 `占位哈希值` Decode 出模糊图片,填充至图片容器(例如 html 中的 img 标签)—— 这一步无需网络,处理时间大约是亚毫秒级,用户看到预加载的占位模糊图不会有任何延迟感
5. 再通过相关 URL 远程加载清晰的缩略图或原图
结合 crop 和 resize(图像缩略、裁剪)参数,可获取原图某一部分的模糊hash
# 签名URL请求次数限制
Source: https://bitiful-docs.mintlify.app/bitiful-s4/features/max-requests-limits
S4 原生支持 x-bitiful-max-requests 限制签名后 URL 的访问次数。
传统的对象存储(Tencent COS、Aliyun OSS、AWS S3)的预签名 URL 只支持时间限制,不支持次数限制,这大大降低了对象存储的安全性。
缤纷云 S4 支持对 GetObject 和 PutObject 的预签名进行次数限制。
## 如何使用
只需在生成预签名 URL 时,加入 `x-bitiful-max-requests=10` 参数(可将后面的 10 修改成你需要限制的次数)
系统会在第 11 次访问的时候返回 403 ReachTheMaxRequests 错误。
安全建议
为 PutObject 签名时,将时间限制在较小范围(如 10分钟),并限制最大请求次数为:1 次,这样可以帮助 PutObject 的签名 URL 杜绝被重放。
## 范例参考
缤纷云开源了一个无状态的 签名URL 生成服务,可支持多种安全参数及独有的性能特性。
| **参数名** | **类型** | **必填** | **默认值** | **说明** | **作用范围** |
| :--------------- | :------ | :----- | :------ | :-------------------------------- | :------------ |
| key | String | 是 | - | 对象的键名/路径,用于在S3存储桶中标识对象 | `PUT` & `GET` |
| content-length | Int | 否 | 不限制 | 上传内容的长度(字节),范围:大于0且不超过1GB(1024MB) | `PUT` |
| no-wait | Int | 否 | 0 | 开启"即传即收"功能的等待超时时间(秒),最大值为10秒 | `GET` |
| **max-requests** | **Int** | **否** | **0** | **最大下载次数限制,指定URL可被访问的最大次数** | `PUT` & `GET` |
| expire | Int | 否 | 3600 | URL的有效期(秒),默认为1小时 | `PUT` & `GET` |
| force-download | Bool | 否 | false | 是否强制下载(设置为true时会添加attachment响应头) | `GET` |
| limit-rate | Int | 否 | 0 | 单线程限速值(字节/秒) | `GET` |
Github:[https://github.com/bitiful/s3-presigned-api-server](https://github.com/bitiful/s3-presigned-api-server)
## 项目集成
缤纷云开源的「**缤纷快传**」较好地利用了这一特性
预览:[https://send.bitiful.com/](https://send.bitiful.com/) 开源地址:[https://github.com/bitiful/send](https://github.com/bitiful/send)
# 移动/重命名对象
Source: https://bitiful-docs.mintlify.app/bitiful-s4/features/move-object
S4 原生支持 Move 和 Rename 操作
传统的对象存储(Tencent COS、Aliyun OSS、AWS S3)均不支持原生的 Move 操作,在 Rename 场景需要先 Copy 对象 再 Delete 对象,开销较大。
缤纷云 S4 支持原生的 Move 操作,可以对文件进行 **高效的 移动 或 重命名 操作**。
# 上下行同步传输技术
Source: https://bitiful-docs.mintlify.app/bitiful-s4/features/simul-transfer
利用 Simul-Transfer 同步传输技术,让文件分享效率提升 100%
## 介绍
### 什么是 Simul-Transfer 同步传输
缤纷云基于自身独有的流式架构,首次为 **「对象存储」** 原生带来了全新的 **「同步传输技术」Simul-Transfer**。它让分享的文件在 **上传开始的一瞬间便可以被下载**,同样的带宽环境下,最多可 **节省1倍的传输时间**。
### 性能如何
它原生植根于缤纷云独有的流式架构中,所以
* **没有任何性能损失**:从上传开始的那一刻开始,便支持 `与普通对象同等的并发、速率水平`\[1]
* **没有任何的功能妥协**:完整支持 缤纷云 S4 `所有的功能特性`\[2],如:防盗链、预签名、Range 请求 等。
### 如何运作
* 传统的对象存储会在文件写入时不会有任何动作,**写入完毕之后,元数据才会感知**,进而对下载请求做出响应。
* 缤纷云新一代对象存储,从上传第一个字节开始,底层的流式架构便可让全局感知,从而让用户从 **上传的第一秒即可开始下载**。
🤔 **without Simul-Transfer: 必须等待上传结束后才能开始下载**
😊 **with Simul-Transfer: 上传开始后,下载也同步开始**
### 和基于 P2P技术 的点对点传输有何不同
以广受好评的 AirDrop 为例,它有几点硬伤:
1. 需要分享者和接收者 **两者同时在线**,成功连线后,并同时操作才可以成功传输
2. 所有接收者下载的时候,都会争抢分享者的上传带宽,即: **接收者越多,人均速度越慢**
3. 对网络要求高:许多苹果的资深用户都知道,**AirDrop 经常失灵**
## 如何体验
### 方法一:体验开源 DEMO:白板
**多人协作场景**
> 在线DEMO: [https://tldraw-bitiful-demo.ladydaily.com/](https://tldraw-bitiful-demo.ladydaily.com/)
Github: [https://github.com/bitiful/tldraw-for-s4](https://github.com/bitiful/tldraw-for-s4)
### 方法二:注册缤纷云
注意
\[1]: 同步下载速率: 在下载进度与上传进度同步后,每个下载线程的速率不会超过上传速度
\[2]: 因 S3 协议的限制,目前暂不支持 Multipart Uploads
# 快速上手 S4
Source: https://bitiful-docs.mintlify.app/bitiful-s4/handbook/quick-start
快速使用 S4 上传和访问内容。
存储桶(Bucket)是用于存储对象(Object)的空间。在上传任意对象前,您需要先创建存储桶。
请确保您已 [注册缤纷云账号](https://console.bitiful.com/) 并完成 [实名认证](https://console.bitiful.com/users)。
### 创建存储桶并上传文件
注册并登录 [缤纷云S4控制台](https://console.bitiful.com/),点击左侧的 **对象存储** 进入 [桶列表](https://console.bitiful.com/buckets)
1. 点击右上角 **创建** 打开创建界面;
2. 输入桶名([命名要求](/bitiful-s4/definitions)),点击“创建”;
3. 若桶名合法,且没有同名冲突,即可创建成功。
1. 回到 [桶列表](https://console.bitiful.com/buckets) 可以看见刚才创建的桶;
2. 点击右上角的 **上传文件**,添加文件有两种方法:
* 从文件管理器拖入 `文件` / `文件夹`到上传区域;
* 点击 `扫描文件` 选取需要上传的文件(可多选),需要上传的文件即会添加至 **待上传** 列表;
* 点击 `扫描文件夹` 选取需要上传的文件夹(单选),文件夹内的所有文件添加至 **待上传** 列表,并自动 `保持原目录结构`;
## 上传单个文件
# 介绍 S4
Source: https://bitiful-docs.mintlify.app/bitiful-s4/intro
介绍缤纷云 S4 对象存储。

[缤纷云 S4](https://www.bitiful.com/)(Smart Simple Storage Service)是一款兼容 S3 协议(S3 Compatible Storage)的对象存储服务。它在 S3 的基础上添加了一系列内置的 **内容处理及优化功能**。故相比 S3 多了 **Smart** 特性。
同时,缤纷云 S4 采用了创新的低成本架构,使得中国大陆用户首次能以不到一半的存储成本使用 [热点云存储](https://wasabi.com/hot-cloud-storage/)(OSS标准、COS标准 等)。
如果需要一个对比,它将类似于:
* [Wasabi.com](https://wasabi.com/) + [Cloudinary.com](https://cloudinary.com/)
* [Backblaze.com B2](https://www.backblaze.com/cloud-storage) + [Cloudinary.com](https://cloudinary.com/)
## S4 的重要特性
缤纷云 S4 重磅推出 [**上下行同步传输 Simul-Transfer**](/bitiful-s4/features/simul-transfer) 技术,可以大幅提升大文件的分享体验:。
* **低成本**:相比 亚马逊S3 和 阿里云OSS,缤纷云S4的使用成本最多可 **降低 80%**(查看:[表格对比](https://docs.qq.com/sheet/DQ3VwTlJQY1l5dU9G))。
* **易使用**:
* 简化的权限体系,全局
* 简洁明了的控制台,所有设置立即生效
* 支持“镜像回源”,低成本迁移历史数据且 **完全不影响业务**
* 原生支持“自定义域名”绑定,并支持 **全自动证书**(配合 [证书中心](/certs-center/intro))
* **高性能**:
* 元数据性能高 —— 缤纷云S4 基于[Directory Buckets](https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/directory-buckets-overview.html);
* 网络性能高 —— 原生支持 Rename、HTTP/2、HTTP/3、TLS1.3;
* **智能化**:
* 使用自研的 CoreIX 媒体处理引擎而非 Imagemagick,可基于内容感知对图片进行自动裁剪、缩略。
* 支持 Webp、Avif 等高级图片格式输出;
* 原生支持 HDR 图片处理、HDR 视频截图;
* 支持内容感知的图片主体内容推测;
* **兼容S3**:亚马逊 S3 是世界范围内用户最多的对象存储服务之一,绝大多数场景可以像使用 S3 一样使用 缤纷云 S4。
* **不分层**:无论是 OSS 还是 S3,都将服务分割成 —— “标准、低频、归档”等以应对不同场景,这不仅会大大增加选型难度,同时会带来容易忽略的大量“隐性”费用,S4 使用一个类型应对所有场景。
缤纷云 S4 的存储桶均为 **目录桶**,约相当于 Amazon AWS 最新推出的:[Directory Buckets](https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/directory-buckets-overview.html)。
AWS 基于它构建了最新的高性能 S3 产品:[S3 Express One Zone](https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/s3-express-one-zone.html)
## 值得注意的限制
目前S4处于预览阶段,正在积极开发中,功能较成熟产品还有很多不足:
* 我们的性能高于 OSS、COS 标准,但请求单价略贵,且目前出口带宽有限。在读取流量较大的场景可搭配 CDN 扩展性能(CDN 目前不计请求费);
* 如果你使用了阿里的服务器,且服务器需要跟对象存储大量交互,则会消耗服务器外网流量,众所周知,阿里云的流量巨贵,总体而言,如果你可以用七牛云、又拍云,基本上完全可以平替过来
* 目前没有 生命周期、服务端加密、WORM、多版本 等特性
## 成本对比
# 约束限制
Source: https://bitiful-docs.mintlify.app/bitiful-s4/limits
介绍缤纷云 S4 对象存储的性能指标和使用限制。
### 当前限制如下:
| 限制项 | 限制说明 |
| -------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `QPS` | - **GET** 类请求:每个地域每个存储桶默认 5000 QPS(单个对象 1000 QPS)。
- **PUT** 类请求:每个地域每个存储桶默认 1000 QPS。
- **List** 类请求:每个地域每个存储桶默认 200 QPS。
- **镜像回源** 请求:全局共享 1000 QPS。
- **普通图片处理**:全局共享 2000 QPS (Or 原图 10GB/s)。
- **高级图片处理**:全局共享 200 QPS (WEBP、AVIF、SVG、RAW、TPNG 等)。
- **视频截图处理**:全局共享 20 QPS (Or 原视频 1GB/s)。 |
| `S4 带宽` | 下载全局 2 Gbps,上传全局 5 Gbps。 |
| `存储桶配额` | 每个主账号最多可以创建 10 个存储桶。 |
| `CDN 配额` | 每个主账号最多可以创建 10 个 CDN。 |
| `证书配额` | 每个主账号最多可以创建 50 个证书。 |
| `自动证书配额` | 每个免费主账号最多可以创建 5 个 LE 单域名自动证书。
每个付费主账号最多可以创建 20 个 GTS、泛域名自动证书(单独计费)。 |
| `对象/文件` | - 简单上传方式最大能够上传 20 GiB文件。
- 分片上传最大能够上传 **195.2 TiB** 文件(每个分片最大 **20 GiB**,分片数量最多 10000)。
- 单个存储桶的文件数量和空间大小均不受限制。 |
| `免费额度` | 实名后每月可享受:
- **50GB存储**;
- **30GB 出口流量(10GB + 10GB + 10GB)**;
- **20万次 S4请求数(10万次 + 10万次)**;
- **无限次 CDN请求数**
的免费额度([详细查看](/prices/basic))。 |
请注意 GiB 与 GB 的区别(缤纷云 与 CDN 出口流量均按 1000 换算)
* *1 GiB = 1024 MiB*
* *1 GB = 1000 MB*
# 用例与场景
Source: https://bitiful-docs.mintlify.app/bitiful-s4/use-case
介绍缤纷云 S4 对象存储适合使用的场景。
## 媒体存储
对象存储可用于海量图片、音频、视频、文档 等内容的存储。
* 基于对象存储特性,可以实现单个目录下海量文件的存放结构,免去设计本地文件系统目录结构带来的性能损耗;
* 配合多媒体智能处理引擎,可实现媒体的缩略、转码、裁剪、格式转换、水印 等实时在线处理;
* 配合 CDN,可实现海量数据的下载分发,实现一整套媒体存储、处理、访问的解决方案。
## 网页静态资源分离
对象存储为 WEB 网站 或 APP应用提供静态资源的存储,如 js 脚本、css 文件、字体 等。配合 CDN 使用,可实现海量用户对同一页面或应用的并发访问。
## 存档备份
### 服务器与工作站
将您的服务器备份到 缤纷云 S4 对象存储是非常简单、经济的。S4 继承了 S3 强大的社区与生态,可与大多数领先的备份软件工具简单地集成,包括 MSP360、Veeam 等等,因此您可以在几分钟内开始使用。最终以 **低于 阿里云OSS 1/3 的热存储费用**,即可享受经济高效地保留备份和存档。
### NAS备份
将您的 NAS 备份到 缤纷云 S4 对象存储是无感知且安全的。S4 费用低廉,前 50GB 存储容量完全免费,并且借助与 S3 协议的良好兼容,可直接用 群晖、威联通、TrueNAS 等内置功能在 **几分钟内完成设置**。
# 快速开始
Source: https://bitiful-docs.mintlify.app/cdn/intro
介绍缤纷云 CDN,及如何快速使用。

请注意,目前仅支持 `静态资源` 加速。
## 简介
缤纷云 CDN 是一个高性能低成本的全球内容分发网络。在全球范围内拥有近 3000 节点,分布在覆盖70多个国家和地区。天然具备弹性能力,无论是每月数千次访问还是数亿次访问,都可以帮助你大幅优化产品(网站、APP)中静态资源的加载速度,同时网络成本。
## 重要特性
CDN 目前 [不计请求费用](/prices/detail/requests-prices)。
* 支持 **全自动证书**(配合 [证书中心](/certs-center/intro))
* 支持 S4 私密桶 和 自定义资源
* 支持全平台 4 层和 7 层联动的 DDoS 防御机制
* 支持 RSA 与 ECDSA **双证书**
* 支持 TLS 1.3、OCSP 装订
* 支持 实时日志、限速
* 基于 referer、UA 和 [高级加密链接](/best-practice/token-link) 防盗链
## 快速开始
请确保您已 [注册缤纷云账号](https://console.bitiful.com/) 并完成 [实名认证](https://console.bitiful.com/users)(可立即享受 10GB/月 [免费额度](/prices/basic))。
注册并登录 [缤纷云S4控制台](https://console.bitiful.com/),点击左侧的 **CDN** 进入 [静态加速管理](https://console.bitiful.com/cdn/list)
1. 点击右上角 **添加新域名** 弹出创建界面;
2. 输入要配置的加速域名(需要备案);
3. 选择要加速的 **加速源** (这里以 S4 存储桶为例);
4. 点击“创建”。
# 🔐 如何申请和管理证书
Source: https://bitiful-docs.mintlify.app/certs-center/intro
## 介绍
缤纷云证书中心统一纳管了平台内所有的证书,支持 **自定义证书** 和 **自动证书** 两种。
**使用说明**
1. 自定义证书暂时无法支持自动更新
2. 目前每个账户支持 5 个免费的 **Let's Encrypt 单域名** 自动证书
3. 从 **2026 年 8 月** 开始 **自动证书** 支持:
1. **Google GTS** 证书
2. **ECC** 证书
3. **多域名** 证书
4. **泛域名** 证书
4. 从 **2026 年 8 月** 份开始 [计费](/prices/detail/autocerts-prices)
## 重要特性
* 域名证书 **全自动创建、续期**(ACME)
* 更换证书自动绑定至 **关联的** S4 存储桶 和 CDN 项目
* 支持 Let's Encrypt、Google Trust Service(2026 年 8 月份开始支持 GTS)
* 支持 **RSA** 与 **ECC** 两种主要证书(2026 年 8 月份开始支持 ECC)
* 支持 [内容证书 API](/developer/api/certs) 将自动证书融入到其他基础设施中
## 体验步骤
请确保您已 [注册缤纷云账号](https://console.bitiful.com/) 并完成 [实名认证](https://console.bitiful.com/users)(可立即享受相应 [免费额度](/prices/basic))。
注册并登录 [缤纷云S4控制台](https://console.bitiful.com/),点击左侧的 **CDN** 进入 [静态加速管理](https://console.bitiful.com/cdn/list)

1. 点击右上角 **申请自动证书**;
2. 输入要配置自动证书的域名,如:cdn.minute.cn(**无需备案**);
3. 前往域名 DNS 托管平台(例如:易名网)设置 **验证 CNAME 记录**;
4. 自取一个 **唯一** 且 **容易记忆** 的证书备注名称(自动证书名称暂不能修改)
5. 点击 **验证** 提示 **CNAME 已配置** 后,点击 **确认申请**
6. 请 **不要关闭申请窗口**,耐心等待一会儿,直到申请完成。
自动证书可应用于:
1. **存储桶** 中绑定的自有域名;
2. **CDN** 中的加速域名;
3. 借助 [内容证书 API](/developer/api/certs) 将自动证书安全、方便地融入到自有基础设施中。
请确保 **存储桶和 CDN 绑定域名** 与 **目标证书** 匹配。
# 产品更新
Source: https://bitiful-docs.mintlify.app/changelog/overview
我们一直在进步
## 自动证书PRO & 对象存储网站 功能上线

### 自动证书PRO

功能更新
1. 新增 **多域名证书** 申请/更新;
2. 新增 **Wildcard 域名证书** 申请/更新(eg: \*.btf.com);
3. 新增 **Google GTS** 证书申请/更新;
4. 新增 **ECC** 证书申请/更新;
更多详情查看:自动证书[免费额度及费用说明](/prices/detail/autocerts-prices)
### 对象存储网站设置
支持设置“**index file**”和“**404 file**”,能让静态资源部署到 S4 对象存储。
## CoreIX V3.0 上线

本次更新,大幅优化了 CoreIX 的 HDR 处理管线,不仅兼容度大大提升,且在业界中首次具备实时 `输入/输出 10 bit ~ 16 bit 色深` 的原生 HDR 图片。下面是我们
以下是 CoreIX V3.0 大幅提升的具体介绍:
1. **全新特性**: 业界首次推出完整的 **实况照片** 处理管线,全面兼容 **live photo(APPLE)/motion photo(OPPO/VIVO/XIAOMI/HUAWEI)** 的提取、互转、合成。欲了解更详细的信息,请加入我们的“企业微信群组”。
2. **HDR 管线 兼容性/特性 优化**:
* 支持 **`高 bit 色深 HDR`** 与 **`8bit GainMap HDR JPEG`** 准确互转;
* 支持 **`AVIF 12bit / HEIC 10 bit / PNG 16 bit / Jpeg XL 16 bit HDR`** 输出;
* 将 **`Raw 格式`** 的 HDR 解析能力从 **Apple ProRaw** 扩展至数十款老设备的 Raw 格式;
3. **准确度**
* 大幅优化 **`HDR 视频截帧转 JPEG`** 的色彩准确度;
* 大幅优化 **hdr-rate** 参数作用于 **原生 HDR 方案图像** 中的准确度(*mark-hdr-rate 参数依旧只能调整 GainMap 方案图像中的水印亮度*);
* 大幅提升 **实况照片中视频** 的水印渲染的准确度(使得实况照片也能具备良好地在线文字/图片水印效果);
* 优化 GIF 动图透明通道的处理准确度。
4. **性能优化**;
* 架构提升:使得 **高比特色深图像** 能在 CoreIX 中得到接近无损的准确处理;
* 大幅提升 AVIF 超大图的编码性能(输出大型 AVIF 图片无需再降级成 JPEG/PNG 了)
### 一张 2022 年的尼康 Raw 图片
在 HDR 的软硬件环境下可以看到下面图片亮度的区别(推荐如:MacBook Pro、iPhone、iPad)
| CoreIX 3.0 | CoreIX 2.5 |
| :---------------: | :---------------: |
|
|
|
横向对比:[国内主流图片实时处理系统性能横向对比](https://tools.bitiful.com/coreix-bench/)
## 📢 政策调整预告
由于严重的滥用问题,S4 将做出以下调整
1. 即日起,S4 对象存储 **不再能直接绑定域名** 对外服务,请 **启用“静态 CDN”**;
2. 从 5 月 11 日起 S4 对象存储将进行单线程限速:
1. 普通文件默认限速 **5MB/s**;
2. 针对 “**ipa/apk**” 文件最高下载速度限制为 **1MB/s**;
* 预计从 5 月 15 日起,S4 对象存储 **不能** 直接对外提供 “ipa/apk” 下载服务,请启用“静态 CDN”;
请 启用 CDN 以获得更高的下载速度及资源加载性能
## CoreIX V2.5 上线

很高兴,我们朝 **做全球最好的图片实时处理 API** 这一目标又迈出了新的一步。
自 CoreIX 在业界第一次支持 PQ/HLG HDR 照片处理开始已过去 2 年,现推出“GainMap HDR”照片处理能力 —— CoreIX 默认会保留包含“HDR 增益图”的照片,并且无论原图是什么 GainMap 方案,CoreIX 都将努力转换成国际标准的 ISO 方案(仅 JPEG 格式输出),以寻求最大化的(显示设备、软件设备)显示兼容性。
以下是 CoreIX V2.5 为你带来的全新能力:
1. **兼容的GainMap格式**:
* 苹果 **`Apple Raw`** 直出照片;
* 苹果 **`GainMap HDR HEIC`** 直出照片;
* 苹果 **`GainMap HDR JPEG`** 直出照片;
* 苹果旧式 **`GainMap HDR JPEG`** 直出照片;
* Adobe **`GainMap HDR JPEG`** 后期照片;
* Google **`UltraHDR JPEG`** 直出照片;
* ISO **`GainMap JPEG`** 直出/后期照片;
* OPPO **`高效 HEIC`** 直出照片;
2. **HDR 相关参数**;
* 新增 **hdr-rate** 参数,限制 HDR 亮度(防止部分 HDR 照片过于刺眼),支持 `绝对值` 和 `百分比` 两种值,*该参数仅对 GainMap HDR 有效*;
* 绝对值:设置处理后照片的最大亮度(0.0 \~ 10.0),建议可以在晚上设置为 0.8 \~ 1.2 以缓解刺眼效果;
* 百分比:将处理后 HDR 照片的最大亮度保留为“原图的指定比例”,如:原图最大亮度为 2.0,`&hdr-rate=50%` 时意味着处理后的照片最大亮度为 1.0
* 新增 **mark-hdr-rate** 参数,设置 GainMap HDR 照片中的水印亮度,传入值为 `百分比`,默认 50% —— 即:原图最高亮度的“一半”,防止水印过亮,破坏原图预期效果,*该参数仅对 GainMap HDR 有效*;
* 参数 **cs** 兼容 GainMap HDR 照片(cs=sdr 时,转换为 SDR 亮度照片);
3. **支持 PDF 转图片**:现在 CoreIX 可以无缝支持 PDF 输入,将指定页数的内容转化成图片(frame 参数)
### GainMap HDR 照片处理效果(图源自 小红书APP)
在 HDR 的软硬件环境下可以看到下面图片亮度的区别(推荐如:MacBook Pro、iPhone、iPad)
| 保留完整亮度 | 保留 70% 亮度 | 去掉 HDR |
| :---------------: | ----------------- | :---------------: |
|
|
|
|
| 完整亮度水印 | 70% 亮度水印 | SDR 亮度水印 |
| :---------------: | ----------------- | :---------------: |
|
|
|
|
横向对比:[国内主流图片实时处理系统性能横向对比](https://tools.bitiful.com/coreix-bench/)
因三大运营商网间结算至带宽成本及存储成本的大幅提升
### 预计从 6 月 21 日起,官网按量计费价格调整如下:
#### CDN **海外节点** 流量单价调整为(大陆地区价格暂时不变):
| 流量(GB) | 单价 |
| ---------------- | --------- |
| `11 ~ 1000 ` | 0.46 元/GB |
| `1001 ~ 10000` | 0.38 元/GB |
| `10001 ~ 100000` | 0.30 元/GB |
| `100000 + ` | 0.24 元/GB |
CDN 流量包不能抵扣海外流量
#### CDN 全球请求单价调整为:
| 请求(万次) | 单价 | 闲时价格(00\~08 点) |
| -------- | ---------- | -------------- |
| `0 ~ 10` | **免费** | - |
| `11+` | 0.035 元/万次 | 0.02 元/万次 |
CDN **全球**请求包限时折扣 **低至 9.9元/亿次**: [https://console.bitiful.com/billing/resource](https://console.bitiful.com/billing/resource)
#### S4 出口流量单价上调:
S4 流量包低至 **0.072元/GB**: [https://console.bitiful.com/billing/resource](https://console.bitiful.com/billing/resource)
| 流量(GB) | 单价 | 闲时折扣(00\~08 点) |
| ---------------- | --------- | -------------- |
| `0 ~ 10` | **免费** | - |
| `11 ~ 1000 ` | 0.26 元/GB | 8折 |
| `1001 ~ 10000` | 0.22 元/GB | 8折 |
| `10001 ~ 100000` | 0.2 元/GB | 8折 |
| `100000 + ` | 0.18 元/GB | 8折 |
#### S4 回源流量单价下调:
| 流量(GB) | 单价 | 变动 |
| ---------------- | ---------- | ------- |
| `0 ~ 10` | **免费** | - |
| `11 ~ 1000 ` | 0.1 元/GB | ↓ 16.7% |
| `1001 ~ 10000` | 0.085 元/GB | ↓ 15% |
| `10001 ~ 100000` | 0.07 元/GB | ↓ 20% |
| `100000 + ` | 0.055 元/GB | ↓ 37.5% |
## S4 对象存储更新 🎉
进一步 **完善 S3 协议 V4 上传校验兼容性**,现在应当可以良好兼容最新的 `Java S3 SDK 2.30.30+` 和 `.Net S3 SDK 4.0.0+`,
即 —— **`SDK 不再需要禁用 Payload Signing 属性`**。
如果你的 SDK 场景仍然存在疑似问题,欢迎加入我们的技术支持群组咨询,我们将尽力提供技术支持。
## 其他调整
由于使用率较低,且大陆出现了较为优秀的同类服务([**Creght**](https://www.creght.cn/))。目前 **Framer 加速服务将关闭新建入口**,现有网站访问会继续维持到 2027 年中旬。
预计从 10 月份起不再优化该服务的可靠性问题,有大陆的相关需求 [**可转移至:https://www.creght.cn/**](https://www.creght.cn/)
## CoreIX V2 上线 🎉

**做全球最好的图片实时处理 API** —— 这是开发 CoreIX 的初衷
基于 **2 年的技术储备**,我们进行 **全面重构**,带来了全新的 **CoreIX V2 版本**。 只要您的项目使用了 [CoreIX API](/coreix/basic) 即可 **自动获得** 下面的收益:
1. **处理性能飞跃提升**:
* 处理 **`相机 Raw 格式`** 图片性能 **大幅提升约 2 \~ 7倍**;
* 处理 `Jpeg` 图片性能 **提升约 60%**;
* 处理 `GIF` 动图性能 **提升约 50%**;
* 转化 `Avif` 静图性能 **大幅提升约 2 - 4倍**;
* 转化 `Avif` 动图性能 **提升约 30% \~ 110%**;
* 处理 `Svg+Xml` 转 `光栅图` 的性能 **提升约 1.2 \~ 2倍**
* 获取 `thumbhash` 性能 **暴涨约 80倍**;
* 获取 `图片主色调` 性能 **暴涨约 50倍**
* 获取 `视频信息` 性能 **大幅提升约 3倍**;
* 转化 `色彩空间` 性能 **提升约 50% \~ 150%**;
* 功耗 `降低约 75%`;
2. **率先支持 APNG 动图处理**;
3. **支持部分 Raw 格式全自动的高级后期能力「PRO」**
* 支持主流镜头 **`几何扭曲`** 的 **`自动矫正`** 处理;
* 支持 **`自动去杂色`** 和 **`自动白平衡`** 高级处理;
* 支持 `部分高级 Raw 格式(如 Apple ProRaw)` 的 **`区域色调映射(Tone Mapping)`** 技术;
4. **大幅提升总体吞吐量的同时功耗降低 75%**
### 大光比照片 Tone Mapping 处理效果
| 不做处理 | CoreIXV1 | CoreIXV2 | 其他友商 |
| ----------------- | -------------------------- | ------------------------- | ----------------- |
|
|
|
|
|
| 丢失暗部细节 | **暗部色彩崩坏**
**天空全面过曝** | **压制高光的**
**还原窗帘光泽** | 格式处理失败 |
横向对比:[国内主流图片实时处理系统性能横向对比](https://tools.bitiful.com/coreix-bench/)
基于此次性能全面提升,所有普通处理将全部免费。高级处理(Raw格式、视频处理、动图 等)价格方案及收费时间预计10月份公布
## 媒体处理更新
### 实时媒体处理 CoreIX 近期更新如下:
1. 调整优化 `thumbhash 哈希占位` 效果;
2. 新增 `主色调获取接口 fmt=color` 将返回 rgba 的 Hex 色值字符串;
3. `SVG 转 图片` 功能上线(当 fmt 指定任意图片格式时);
* 可以有效避免 **SVG 源文件的泄漏风险**;
* 可为 SVG 带来 **完整的图片处理** 支持,包括 —— **水印**、**缩略图**、**主色调**、**模糊** 等;
* 优化兼容性 —— 在不支持 SVG 客户端中,可以获得 **无缝的转换兼容**。
4. 使用 `fmt=keep` 参数将输出 **安全的 SVG 源文件**(Xml),能杜绝:
* **SVG Xml 中的跨站脚本(XSS)攻击** —— 清理 SVG 文件中的脚本;
* **SEO 垃圾邮件和网络钓鱼** —— 清除指向其他域的超链接;
* **第三方追踪** —— 删除对跨域资源的引用。
CDN 请求包低至 **0.09元/亿次**: [https://console.bitiful.com/billing/resource](https://console.bitiful.com/billing/resource)
## 📊 控制台统计数据异常说明
**省流:**
不影响任何服务稳定性,不影响存储数据安全
少算的费用 **不会追缴**;多算的费用将 **单独补偿**。
### 7月12日 由于数据基础设施故障叠加监控 BUG 之问题:
**将影响**:
* **S4 出口数据** —— 对象存储 `统计图表` 中 `S4 出口数据` 和 `回源数据` 将低于实际数据
* **S4 流量计费** —— **所有** 账户 `当日计费` 低于预期(于账户角度意味着 `少付钱`)
* **S4 阶梯计算** —— **少部分** 账户会因 `阶梯清零` 导致未来一段时间每个周期扣费会略高于预期(我们会在周一前会补偿 CDN 流量包到账户中)
* **实时日志** —— 包括 S4、CDN
**不影响**:
* CDN 出口数据
* CDN 计费 & 阶梯
## 媒体处理更新
### 实时媒体处理 CoreIX 近期更新如下:
1. `预览模糊功能 fmt=thumbhash` 大幅优化性能和效果;
2. `媒体信息获取接口 fmt=info` 新增 **视频**、**音频** 的支持;
3. `内容识别 OCR 接口` 测试上线,可支持 **视频**、**图片** 中的文字识别;
* 支持多达 **15 种不同语言的自动识别**;
* 无缝支持 **视频、动图** 的 frame 参数(截帧);
* 付费客户目前可免费测试,请联系客服申请。
## 🎁 流量、请求数资源包以及折扣活动上线
### 资源包特点:
1. 购买相应的资源包后可直接抵扣消耗的资源;
2. 资源包抵扣时没有最低计算单位的限制(例如:用余额抵扣请求数消费时最低单位是“千次请求”)
3. 可用余额购买资源包,若之前使用优惠券充值,相当于折上折;
4. 转回“按量计费”后,所有资源包抵扣量依然参与本月阶梯计算。
### 特别折扣
7月7日前购买:**1TB** 和 **10TB** 的 **CDN资源包** 最低可享受 **6 折**(每个账户限购一次)。
购买地址:[https://console.bitiful.com/billing/resource](https://console.bitiful.com/billing/resource) (右上角 **购买资源包**)
## 🧑💻 证书中心上线「获取证书内容」API
### 证书中心上线:
将该 API 融入系统内部的工作流脚本中,可以实现 **全局自动更新域名证书**。
[https://docs.bitiful.com/developer/api/certs](/developer/api/certs)
## ☀️ 全新「证书中心」正式上线
**支持域名证书全流程自动处理:签发、续期、托管、更换**
完全不用再担心证书过期,[赶紧来体验](https://console.bitiful.com/certs/manage)。
### 使用演示
## 🙅♀️ 拒绝被滥用,S4 可自动检测 M2TS 和 M4S 类型
年初发生了一起震惊开发者圈的 **供应链滥用事件**:
[npm 被上传了 748 个武林外传的视频 ts 切片文件](https://www.sonatype.com/blog/npm-flooded-with-748-packages-that-store-movies)
攻击者利用 **typescript** 和 **mpeg2-ts** 后缀相同的特点,将大量视频切片上传到 npm 后盗链下载,消耗了大量宝贵的公益资源。
针对该类情况,缤纷云 S4 的 [**媒体类型自动检测系统**](/best-practice/auto-detect-mime) 优化了对视频切片的判断策略,善加利用可以 **有效杜绝** 此类攻击。
## 🎉 双 11 充值折扣券上线
缤纷云 11.11 大额充值券
充值用券:
* 使用 BTF20241111A 送 **20%**,充100起送
* 使用 BTF20241111B 送 **30%**,充500起送
* 使用 BTF20241111C 送 **50%**,充100起送 (限首充) (长按 券代码 可复制)
时间:2024年11月10日 ~ 2024年12月10日
## 💳 上线支付宝支付
支付系统上线 **支付宝**。
## 🚀 大幅优化 CDN 部署时间
将 CDN 的部署时间从 **数分钟** 大幅优化至 **30s** 内,大大改善 CDN 的配置体验。
## 🧑💻 上线部分 CDN 与 数据 API
### S4 上线:
* 容量、文件数 API
* 实时日志 API
[https://docs.bitiful.com/developer/api/s4](/developer/api/s4)
### CDN 上线:
* 边缘流量、回源流量 API
* 边缘请求数、回源请求数 API
* 实时日志 API
* 缓存刷新 API
[https://docs.bitiful.com/developer/api/cdn](/developer/api/cdn)
## **📄 媒体处理 Style 支持可变参数**
在设置 Style 的参数时,现在可以通过在 **参数前增加 \* 符号** 使该值 **可被 Url 参数自定义**。
以上图的参数举例:
* w(宽度像素) 是 **不可变参数**,代表设置到 Style 后,该参数 **固定为 1200**,不可被 Url 参数 改变;
* txt(水印文字)是 **可变参数**,代表设置到 Style 后,该参数 **默认为 @Bitiful**,但可以被 Url参数 改变。
建议 不要 将图片处理的 **格式**、**宽度**、**高度** 等 影响文件大小 的参数设置为 **可变参数**。
## **📄 CoreIX 支持获取文件元数据信息功能**
## 将 fmt 参数设置为 info 即可获取对象元数据信息
›› 例子:[https://demo.bitiful.com/girl.jpeg?fmt=info](https://demo.bitiful.com/girl.jpeg?fmt=info)
当 **fmt=info** 时,CoreIX 的其他参数将不会生效。这是为了确保最终输出的是 **原始对象的元数据**。
## 🛜 缤纷云开源 Wetransfer 替代项目:[Bitiful Send](https://github.com/bitiful/send)
#### 介绍
[Wetransfer](https://wetransfer.com) 和 [奶牛快传](https://cowtransfer.com) 的开源替代。
支持缤纷云领先的独特功能「即传即收」。
#### 特点
1. 高性能广兼容:支持兼容 S3 协议的对象存储直传直取,**不经过服务器中转**,性能最大化;
2. 依赖简单:\**无账户体系*、无各种 **数据库依赖**,自部署只需简单配置;
3. 功能完整:下载链接 **限速**、**限时**、**限次**;
4. 架构、代码简单,易于改造和二次开发。
相关链接:
* Github [https://github.com/bitiful/send](https://github.com/bitiful/send)
* Demo [https://send.bitiful.com/](https://send.bitiful.com/)
## **🛜 缤纷云发布 Simul-Transfer 技术,让文件分享 0 等待**
## 上下行同步传输技术
缤纷云基于自身独有的 **流式架构**,再次首创为 **「对象存储」** 原生带来了全新的 **「同步传输技术」Simul-Transfer**。它让分享的文件在 **上传开始的一瞬间便可以被下载**。
›› [进一步查看](/bitiful-s4/features/simul-transfer)
## **🔐 S4 对象存储支持签名URL请求次数限制**
### 推出 x-bitiful-max-requests 参数
利用 S4 该特性可进一步保护你的上传下载,例如:
1. 在需要 `限制下载次数` 的场景(例如:分享文件),杜绝黑产嗅探到真实下载地址无限下载;
2. 保护你的 **上传链接** 不被重放攻击
在缺乏 **次数限制** 的情况下,黑产可以在极短的时间内对 上传URL 进行重放攻击,达到上传违规文件的目的。
›› [进一步查看](/bitiful-s4/features/max-requests-limits)
## **✏️ S4 对象存储生产支持 Move 操作(原子 Rename)**
### Rename 性能提升 1000 倍
传统的对象存储(Tencent COS、Aliyun OSS、AWS S3)均不支持原生的 Move 操作,在 Rename 场景需要 借助 `Copy + 校验`达到 Move 目的。
单个大文件的 `Copy + 校验` 过程很可能 **长达 10 秒** 以上,在部分场景中会 **严重降低整体性能**。而 Move 操作耗时可 **低至 5 毫秒内**。
原子 Rename (Move)拥有 **巨大优势**:
* **强一致** - Move 前后 **没有任何中间状态**,操作成功后全局立即生效;
* **强可靠** - 没有 Copy 过程,**完全不会影响原数据的安全**;
* **低成本** - 没有 Copy 过程,**不会占用双倍的存储容量**;
* **高兼容** - 使用 **控制台** 和 简单的 **CopyObject 接口**,可 Rename 任意大小对象;
例如:阿里云 OSS **控制台** 和 **CopyObject** 不能 [重命名大于 1 GB 对象](https://help.aliyun.com/zh/oss/developer-reference/copyobject)
## **🌍 缤纷云全球CDN节点上线**
### 一键轻松切换
现在可以通过简单地修改CDN配置,完成「**仅大陆节点**」和「**全球节点**」的切换。
### 自动优化跨境回源(当前免费)
海外节点在回源S4存储桶时会进行全自动的跨境优化(自定义网站回源暂不支持)。
请务必保持控制台中正确的 CNAME 记录。
## 🕥 存储 & CDN 实时访问日志上线!
为了让客户进一步观测自己的请求数据,我们上线了实时访问日志。
这几乎是业界首次直接免费提供(不用开通额外服务、不用考虑计费)实时访问日志。
在海量的访问下,要免费开放并维持这一能力并不容易,希望能与各位客户一起提高与进步。
目前提供的功能还比较简单,但我们相信这是一个好的开始~
### **基于流式数据架构的近实时观测能力**
得益于缤纷云先进的流式数据架构,让我们有能力为用户提供各种近乎实时的观测数据。
例如:在桶列表当中,对象的总容量与总数的数据更新近乎总是在1分钟内,这使我们更容易对总体情况进行把握和预测。
## 原文件保护功能增加「默认Style」功能
源文件保护功能,可以在非「预签名」情况下最大程度保护您的原创作品。
设定了指定MIME源文件保护后,您的用户在匿名访问的情况下访问该媒体(未经处理)的原文件会报错:403 OriginalFileProtected。
在这种情况下,用户访问该媒体的方法只有:
1. 使用预签名Url访问(使用预签名Url方式在S4当中一直拥有最高权限);
2. 使用您设定的某个Style访问(例如:[https://bucket.s3.bitiful.net/image.jpg!style:](https://bucket.s3.bitiful.net/image.jpg!style:\{\{styleName}}))
这无疑为您的媒体内容提供了巨大的保护能力。
### 更优雅的源文件保护(设定默认Style)
但为用户返回「403 OriginalFileProtected」的报错信息未必是最优雅的方案。
现在:缤纷云S4允许您为保护内容设定一个已存在的默认Style。
当您的用户触发源文件保护的时候,系统不会返回「403 OriginalFileProtected」的错误信息,而是按照上面指定的默认Style对媒体进行处理,然后返回给用户。
## 缤纷云 服务运行状态监控页(status page)上线
### 独立架构
缤纷云服务状态监控页面测试上线啦。
它运行在完全独立的基础设施当中,可以在缤纷云服务遇到问题时依然保持观测能力。
访问:[https://stack-status.com/](https://stack-status.com/)
🧪 实验特性
## 缤纷云S4对象存储访问节点现已支持HTTP/3(QUIC)
## 概念
QUIC (HTTP 3) 通常被称为下一代网络通信。它运行在 OSI 模型的第四层,过去代表"快速 UDP 互联网连接"(现在起草的规范指出"QUIC"是协议的实际名称,而不是其他任何内容的缩写)。它也被称为 HTTP/3,进一步巩固了其作为 HTTP/2 继承者的地位。
### 基于 UDP
QUIC协议最关键的一点是使用UDP进行通信;仅此一项就可以通过放弃使用传统的基于 TCP 的安排(需要任何两方同步,然后是 SYN-ACK 和确认)来降低客户端和服务器之间的延迟。
### 缤纷云S4对象存储访问端点全面支持HTTP/3(QUIC)
若您希望体验HTTP/3,并且您的桶域名 [https://xxx.s3.bitiful.net](https://xxx.s3.bitiful.net) 在访问时还没有看到h3协议:
请与群中客服联系。
强大的 CoreIX 变得更强
## 🌟 CoreIX 支持 Blurhash 和 Thumbhash
缤纷云 CoreIX 上线实时的 Blurhash & Thumbhash 功能。
这是缩略图预加载的最佳实践,效果出类拔萃。
从现在开始,立即使用简单的 `fmt=blurhash` 或 `fmt=thumbhash` 获得全新的预加载效果。👇👇👇
## 🖥 全新的缤纷云控制台已经上线!
更美观、更方便,适配更多的屏幕尺寸。
强大的缤纷云媒体引擎
## ‼️ CoreIX 支持高级文字水印
如下图,依靠强大的 [文字水印参数](/coreix/basic) 实现艺术一般的水印效果。
只需要设定几个参数,CoreIX 会在 0.1 秒内 呈现给您的用户。
今天缤纷云正式发布了
## 🎁 缤纷云 S4 智能对象存储 正式发布
你好,2024年,你好,缤纷云。
# CoreIX 概述
Source: https://bitiful-docs.mintlify.app/coreix/basic
介绍缤纷云 S4 自带的媒体处理功能 CoreIX。
**CoreIX** 是缤纷云自研的,具有高度 **自动化**、**智能化**、**高兼容性** 的 **高性能** 实时 **媒体处理引擎**。
S4 对象存储中的媒体内容可以简单地通过在 Url 末尾(或在 GetObject 接口中)携带相关 **处理参数** 轻松获得 **CoreIX** 的 **所有丰富功能**。
**注意** 当前处于测试阶段,暂不收费。收费时间及标准会另行通知,请您及时关注相应公告。
## CoreIX 独有特点
1. **超高性能**:性能最多可达国内主流图片处理性能的 **10 倍** 以上;
2. **独家支持颜色管理**:国内唯一可准确高性能处理 **CMYK 色彩模式** 的实时媒体引擎;
3. **独家超大图处理**:CoreIX 允许高性能处理 **高达 200MB** 的图片;
4. **独家全流程 HDR 管线支持**:可以输出 **HDR 图片**,也可映射为 **SDR 图片**;
5. **独家画面感知能力**:在必须裁剪画面时可 **自动保留画面主体**;
6. **独家原生支持 SVG**:可以将 SVG 转成光栅图,也可作为 **水印图**;
7. **独家哈希占位支持**:原生支持 **Thumbhash** 和 **Blurhash** 码输出;
8. **独家原生支持 RAW 格式**:兼容主流 RAW 格式,支持`镜头畸变矫正`、`Tone Mapping`、`原生高 bit HDR`;
9. **独家支持量化压缩**:CoreIX 支持 `fmt=tpng` 参数,可原生获得类似 TinyPNG 的处理效果;
10. **独家 OCR 内置**:CoreIX 会 **自动优化图片并识别文字内容**,无需编写复杂的代码调用第三方 API;
11. **独家 Live Photo 完整支持**:CoreIX 能支持 iOS 和主流安卓实况照片方案的`静图/视频提取`以及`转换/合成`
### 高度集成的自动优化:
* **自适应方向**:可依据原图的 Exif 信息对图片做自动的方向调整处理,支持带 Exif 信息的 Jpeg、PNG、Webp、Avif、Heif 和 主流相机 Raw 图;
* **自动删减 Exif**:在快速分享场景中,Exif 没有实际作用,去掉 Exif 可减少相应传输流量,此举最多可节省约 `500 KiB` 容量;
* **自动颜色管理**:CoreIX 生成缩略图时,会自动进行必要的颜色空间转换,然后删除 ICC profile,此举对于特殊色彩空间的图片最多可节省约 `2.5 MiB` 容量;
* **可转换 Tinysrgb**:对于包含 sRGB 的原图,在生成小号缩略图时,CoreIX 会自动用 Tinysrgb 替代,此举通常可节省 `3 KiB` 容量;
* **自动支持 HDR**:在对 HDR 视频进行截图(取帧)操作时,CoreIX 将默认自动输出 HDR 图片,指定 `cs` 参数为 srgb 时将自动把色彩空间映射为 SDR,避免出现灰图;
* **高度集成**:所有参数
* **~~客户端协商机制~~**~~:当设定输出格式为 fm=webp 时,系统将通过 Accept 判断客户端是否支持 webp 图片;~~(鉴于 HTML type 标签的完善普及,以及 webp、avif 等格式已被大范围原生支持,该特性已正式下线)
## 图片处理功能
1. CoreIX 关心图片的最终分享效果,包括准确度与访问速度。所以在每次执行`手动参数`前,都会对图片做必要的自动优化,以最大程度达到`处理效果`与`节省流量`的最佳平衡。
2. CoreIX 在生成分享图时做实时处理,所有操作均不会造成对存储桶中原图的修改。
### 手动参数:
| 限制项 | 相关参数 | 作用说明 | 范围 |
| :--------------------------------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------- | ------ |
| [缩略宽高](/coreix/features/resize) | - w: 图片宽度
- h: 图片高度 | 将图片缩放至指定大小。 | 全部 |
| [缩放倍数](/coreix/features/resize) | - dpr: 倍数值 | 可简易设置 2x 3x 大小缩略尺寸。 | 全部 |
| [缩略模式](/coreix/features/resize) | - mode: crop / clip | 当设定w、h全部指定且与原图比例不符时。 默认使用 crop 裁剪缩略模式。 | 全部 |
| [保留位置](/coreix/features/resize) | - pos: 缩略裁剪模式情况下保留的部分 | 缩略裁剪后提取的保留部分。 | 全部 |
| [自定义裁剪](/coreix/features/crop) | - rect: 裁剪坐标与大小 | 裁剪指定位置和大小的矩形图片。 | 静图 |
| [质量变化](/coreix/features/quality) | - q: 质量百分比 | 调整 JPG、GIF(动图)、WebP(动、静图)、Avif 格式图片的质量。 | 全部 |
| [图像锐化](/coreix/features/sharp) | - sharp: 锐化程度 | 对图片进行锐化效果处理。 | 静图 |
| [图像模糊](/coreix/features/blur) | - blur: 模糊程度 | 对图片增加模糊效果。 | 静图 |
| [文字水印](/coreix/features/watermark) | - txt: 水印的文字内容 | [详细参数](features/watermark) | 静图 |
| [图片水印](/coreix/features/watermark-image) | - mark: 水印图片的桶内路径 | [详细参数](features/watermark-image) | 静图 |
| [视频截图](/coreix/features/frame) | - frame: 毫秒数(视频)或 帧数(GIF) | 格式支持:MP4、MKV; 色彩支持:SDR 视频 / BT.2020/2100 色域 HDR 视频 \* 注意:frame 只能对已经存入 S4 对象存储的文件生效 (镜像回源场景下回源成功后才会生效) | 动图 视频 |
| [色彩空间](/coreix/features/colorspace) | - cs: ColorSpace | 设定希望输出的色彩空间,支持:tinysrgb、srgb、adobe rgb | 静图 |
| [修剪边框](/coreix/features/trim) | - trim: [详细参数](/coreix/features/trim) | 用于自动去除图像四周的 **纯色边框** 或 **透明边框** | 静图 |
| [格式转换](/coreix/features/fmt) | - fmt: 格式代号 | 图片格式:jpeg、png、tpng、webp、bmp、avif、gif、tiff - 其他格式:blurhash、thumbhash、json(输出图片、视频信息) | |
**自2024年1月1日起,将支持 GIF / WEBP 动图支持高性能缩略、裁剪处理**
## 图片处理方法
直接在图片类型对象的 Url 末尾加上相应参数即可使用。
#### 示例 URL 如下:
```text theme={null}
原图:https://demo.bitiful.com/girl.jpeg
```
加上处理参数后:[**`https://demo.bitiful.com/girl.jpeg?w=800&h=500&pos=top`**](https://demo.bitiful.com/girl.jpeg?w=800\&h=500\&pos=top)

# 图像模糊
Source: https://bitiful-docs.mintlify.app/coreix/features/blur
图像模糊参数为 blur,可为图片增加模糊效果。
## 参数说明
该方法只能用于静态图片
### 相关参数总览
| 参数 | 含义 | 作用说明 |
| :----- | ------------ | ----------------------------------------------------- |
| `blur` | 指定**模糊效果强度** | - 取值范围:
0 \~ 500(默认为 0)
- 取值含义:取值越大,模糊强度越高。 |
### 效果演示
原始图片:

模糊度设置为 10:[https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&q=90 **`&blur=10`**](https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&q=90\&blur=10)

模糊度设置为 50:[https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&q=90 **`&blur=50`**](https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&q=90\&blur=50)

# 色彩管理支持
Source: https://bitiful-docs.mintlify.app/coreix/features/colorspace
CoreIX 支持色彩管理,包括 不同色彩模式 和 主流色彩空间 的支持(P3、CMYK、HDR、Adobe RGB、ProPhoto RGB 等)。
## 色彩空间介绍
色彩空间定义了颜色在数字图像中的表示方式。CoreIX 支持处理多种专业色彩空间:
* **P3 色域**:用于数字影院和高端显示设备的广色域标准
* **CMYK 色彩空间**:印刷行业标准,使用青、品红、黄、黑四色
* **HDR(高动态范围)**:提供更广的亮度范围和更丰富的色彩表现
* **sRGB**:标准网络和显示设备使用的色彩空间
* **tinysrgb**:轻量级 sRGB 实现,适用于资源受限环境
## CoreIX 色彩空间支持
### 支持功能
1. **色彩空间识别**:自动检测图像的原始色彩空间
2. **色彩空间转换**:支持将图像转换到目标色彩空间(如 **P3** / **CMYK** / **Adobe RGB** → **sRGB** 的输出)
3. **HDR 映射**:将 **HDR** 内容正确映射到 **SDR** 显示设备
4. **色域保留**:在处理过程中保持原始色域的完整性
该方法只能用于静态图片
### 相关参数总览
| 参数 | 含义 | 作用说明 |
| :--- | -------------- | -------------------------------------------- |
| `cs` | 指定 **输出的色彩空间** | - 取值范围:
keep、p3、srgb、tinysrgb(默认为 keep) |
## 色彩空间处理演示
### 不同色彩空间处理效果对比
| 色彩空间 | 保持 ICC (cs=keep) | 删除 ICC (cs=strip) | **智能映射 ICC** (cs=srgb) |
| :------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------- |
| **P3 色域**
[查看原图](https://coreix-demo.s3.bitiful.net/p3_files/p3.jpg) |  |  |  |
| **CMYK 色彩**
[查看原图](https://coreix-demo.s3.bitiful.net/cmyk_files/cmyk2.jpg) | 
**700 KiB** | 
**62 KiB** | 
**60 KiB** |
| **HDR 图像**
[查看原图](https://demo.bitiful.com/hdr-img/trees.avif) |  |  |  |
* **tinysrgb 说明**:CoreIX 提供轻量级 tinysrgb 实现,在保持 sRGB 标准兼容性的同时减少 40% 内存使用,适合移动设备和低资源环境;
* **HDR 视频截帧说明**:[HDR 内容实践](/coreix/features/colorspace)
# 自定义裁剪
Source: https://bitiful-docs.mintlify.app/coreix/features/crop
图片自定义裁剪可以按坐标从原图中提取任意区域。本文介绍自定义裁剪的参数说明及使用示例。
以下例子中,默认原图均为:[https://demo.bitiful.com/girl.jpeg](https://demo.bitiful.com/girl.jpeg)
## 参数说明
该方法只能用于静态图片
### 相关参数总览
| 参数 | 含义 | 作用说明 |
| :----- | -------------- | ------------------------------------------------------------------- |
| `rect` | 指定 **裁剪坐标与长宽** | - 共4个值,均为数字,半角逗号隔开
- 参数分别为:**x, y, w, h**
- 如:0,0,500,500 |
### 用例说明
* **x、y**:代表左上角的 x, y 轴坐标
* **w、h**:与 [缩略图](resize.md#相关参数总览) 中的 w、h 含义相同,代表截取目标的 宽、高

加上参数后 URL:[https://demo.bitiful.com/girl.jpeg? **rect=0,0,500,500**](https://demo.bitiful.com/girl.jpeg?rect=0,0,500,500)

由于 参数 rect 的优先级高于 w 和 h,于是:
1. 所以系统会优先按照参数 `rect=0,0,1000,1000` 提取原图左上角开始的 1000 x 1000 区域图像;
2. 然后将 1000 x 1000 的正方形图像按照参数 `w=500` 将 rect 处理结果缩略至 500 x 500;
**所以**:按照[图片缩略逻辑](resize.md#用例说明)单独设定 w=500,系统会按\*\*`rect 结果图像的宽高比`\*\*(而非`原图的宽高比`)自动设定缩略高度。
加上参数后 URL:[https://demo.bitiful.com/girl.jpeg? **rect=0,0,1000,1000 & w=500**](https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=500)

# 图片格式转换
Source: https://bitiful-docs.mintlify.app/coreix/features/fmt
图片格式转换参数为 fmt,可指定图片的输出格式。
# 图片格式转换
## 参数说明
该参数影响图片的输出格式,可能会改变文件大小、质量和兼容性
### 相关参数总览
| 参数 | 含义 | 作用说明 |
| :---- | ------------ | ------------------------------------------------------------------------------ |
| `fmt` | 指定**图片输出格式** | - 取值:
jpg、png、webp、avif、gif等多种格式
- 作用:
根据需求转换图片格式,平衡文件大小、质量和兼容性 |
### 支持的格式及说明
完善支持以下 **基本格式**:
| fmt 值 | 对应格式 | 特点说明 |
| :----------- | ---- | -------------------------- |
| `jpg`/`jpeg` | JPEG | 有损压缩格式,适合照片,不支持透明度 |
| `png` | PNG | 无损压缩格式,支持透明度,文件较大 |
| `gif` | GIF | 支持简单动画和透明度的格式,色彩有限(256色) |
| `tiff` | TIFF | 专业级无损图像格式,支持多层和高色彩深度,文件较大 |
| `bmp` | BMP | 无压缩位图格式,文件较大,兼容性好 |
| `keep` | 自动 | 输出原本图片格式,若为 SVG,则会自动过滤危险代码 |
和以下 **高级格式**:
| fmt 值 | 对应格式 | 特点说明 |
| :------------ | ---------- | -------------------------------------- |
| `tpng` | PNG | 使用图像量化优化的PNG格式,减小文件体积(参考:TinyPNG) |
| `gif` | GIF (动图) | 支持简单动画和透明度的格式,色彩有限(256色) |
| `webp` | WebP (含动图) | 谷歌开发的现代格式,同时支持有损和无损压缩,支持透明度和动画,兼顾质量和体积 |
| `heic`/`heif` | HEIC (高级) | 苹果推广的高效图像格式,压缩率高,支持透明度和多图层 |
| `avif` | AVIF | 新一代图像格式,提供更高压缩率,保持高质量,支持透明度和HDR |
此外,利用特殊 fmt 值还支持以下 **高级扩展特性**:
| fmt 值 | 对应格式 | 特点说明 |
| :---------- | ------------------------------------------------- | ----------------------------- |
| `color` | TXT | 返回图像元数据信息而非图像内容 |
| `blurhash` | [BlurHash](bitiful-s4/features/hash-placeholder) | 图像占位符格式,将图像编码为简短字符串,用于加载预览 |
| `thumbhash` | [ThumbHash](bitiful-s4/features/hash-placeholder) | 类似 BlurHash 的图像哈希格式,生成小缩略图哈希值 |
| `info` | JSON | 返回图像元数据信息而非图像内容 |
### 效果演示
原始图像:

转换为WebP格式:[**`https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000&w=300 &fmt=webp`**](https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&fmt=webp)

转换为PNG格式(保留完整质量):[**`https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000&w=300 &fmt=png`**](https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&fmt=png)

转换为AVIF格式(最高压缩率):[**`https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000&w=300 &fmt=avif`**](https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&fmt=avif)

### 格式选择指南
* **JPEG/JPG**: 适用于照片和复杂图像,不需要透明度时的最佳选择
* **PNG**: 需要透明度或图像质量无损时使用
* **WebP**: 现代网站的推荐格式,兼顾质量和体积
* **AVIF**: 追求最佳压缩效果时使用,但浏览器兼容性较新
* **GIF**: 简单动画需求时使用
* **HEIC/HEIF**: 苹果生态系统内使用,压缩效率高
### 使用提示
* 在不指定`fmt`参数时,系统会根据原始图像类型选择合适的输出格式
* 参数别名:`fm`也可以用作`fmt`的替代
* 部分格式(如AVIF、WebP)可能不被所有浏览器支持,系统会自动降级到兼容格式
* 与`q`(质量)参数结合使用可以更精细地控制输出图像
# 视频和动图截帧
Source: https://bitiful-docs.mintlify.app/coreix/features/frame
使用 frame 参数从视频或动态图像中提取静态帧
## 参数说明
**frame** 参数允许从视频文件或动态图像(如GIF)中提取特定时间点或位置的静态帧。这对于缩略图生成、视频预览或提取动画中特定场景非常有用。
### 基本用法
| **参数** | **类型** | **默认值** | **说明** |
| :-------- | :----- | :------ | :----- |
| **frame** | 整数 | `1` | 提取帧的位置 |
## 详细说明
**frame** 参数在不同媒体类型下有不同的含义:
#### 视频文件
当处理视频文件时,**frame** 参数表示 **时间点**,单位为 **毫秒**:
* `frame=0` - 提取视频的第一帧
* `frame=5000` - 提取视频开始后5秒处的帧
* `frame=60000` - 提取视频开始后1分钟处的帧
#### 动态图像(GIF、动态 WebP 等)
当处理动态图像时,**frame** 参数表示 **帧的序号**,从1开始计数:
* `frame=1` - 提取动态图像的第一帧(默认值)
* `frame=2` - 提取动态图像的第二帧
* `frame=n` - 提取动态图像的第n帧
如果指定的帧数超出动态图像的实际帧数,将返回最后一帧。
### 示例用法
原视频:[https://demo.bitiful.com/hdr-img/rainbow.mov](https://demo.bitiful.com/hdr-img/rainbow.mov) 截取 **第 4950 毫秒** 的关键帧作为图片 [https://demo.bitiful.com/hdr-img/rainbow.mov?frame=4950\&w=1000](https://demo.bitiful.com/hdr-img/rainbow.mov?frame=4950\&w=1000)

# 质量变换
Source: https://bitiful-docs.mintlify.app/coreix/features/quality
质量变换可以对处理后的图片输出时做质量压缩,以尽可能节省传输流量。本文介绍质量变换的参数说明及使用示例。
以下例子中,默认原图均为:[https://demo.bitiful.com/girl.jpeg](https://demo.bitiful.com/girl.jpeg)
## 参数说明
该方法只能在输出 `Jpeg 静图` / `Webp 动、静图` / `Avif 动、静图` / `GIF 动图` 使用(fmt=jpg / fmt=webp / fmt=avif)
### 相关参数总览
| 参数 | 含义 | 作用说明 |
| :-- | --------------- | ------------------------------------- |
| `q` | 指定**图片输出质量百分比** | - 设置图片的绝对质量,将原图质量压缩至 q%
- 默认值:88 |
### 用例说明
* **q**:如果原图质量小于指定参数值,则按照原图质量重新进行压缩。例如 原图质量是95%,添加 q=90 参数后最终会得到质量90%的图片。
### 对比效果
质量转换为 90%:[https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300& q=**90**](https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&q=90)

质量转换为 20%:[https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300& q=**20**](https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&q=20)

# 图片缩放
Source: https://bitiful-docs.mintlify.app/coreix/features/resize
图片缩放功能可以对原图大小进行调整。本文介绍图片缩放功能的参数说明及使用示例。
以下例子中,默认原图均为:[https://demo.bitiful.com/girl.jpeg](https://demo.bitiful.com/girl.jpeg)
## 参数说明
### 相关参数总览
| 参数 | 含义 | 作用说明 |
| :----- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `w` | 指定 **宽度** | 系统将图片宽度缩小到 w 的值。 |
| `h` | 指定 **高度** | 系统将图片高度缩小到 h 的值。 |
| `dpr` | 额外 **缩放比** | - 默认:1,代表不缩放
- 范围:0.01 \~ 10,该参数为额外缩放系数 |
| `mode` | 指定 **缩略模式** | - crop:裁切模式
- clip:等比模式 |
| `pos` | 指定 **裁剪保留位置** | - center:居中(默认)
- top:保留中间和上侧
- bottom:保留中间和下侧
- left:保留中间和左侧
- right:保留中间和右侧
- top-left:保留上侧和左侧
- top-right:保留上侧和右侧
- bottom-left:保留下侧和左侧
- bottom-right:保留下侧和右侧
- top-center:保留居中偏上侧
- bottom-center:保留居中偏下侧
- left-center:保留居中偏左侧
- right-center:保留居中偏右侧
- auto BETA:自动推测画面重点(尽力而为) |
### 用例说明
* **单独设定 w 或 h**
* 若单独指定 w 参数(不指定 h):系统会按 `等比模式 mode=clip` 将图片 **等比缩小** 为 宽度为 w 大小的缩略图。
* 若单独指定 h 参数(不指定 w):系统会按 `等比模式 mode=clip` 将图片 **等比缩小** 为 高度为 h 大小的缩略图。
* **同时设定 w 和 h**
* 系统会自动按 `裁切模式 mode=crop` 将图片 **强行裁剪** 为 w、h 设定大小的缩略图,默认取中间部分,丢弃多余部分。
* **同时设定 w 和 h,且指定 mode 为 clip**
* 系统会自动按 `最小模式 mode=clip` 将图片 **等比缩略** 到 w、h 的矩形盒子内,即:缩略图的长、宽均不会超过设定的 w、h 值。
* **设定 dpr**
* 以上面 `w=300&h=300` 为例:
* 且 `dpr=2` 时:系统会生成 `600x600` 的正方形缩略图
* 且 `dpr=0.5` 时:系统会生成 `150x150` 的正方形缩略图
## 参数范例
加上参数后 URL:[**https://demo.bitiful.com/girl.jpeg? w=200**](https://fanfan.s3.bitiful.net/girl.jpeg?w=200)

加上参数后 URL:[**https://demo.bitiful.com/girl.jpeg? h=200**](https://demo.bitiful.com/girl.jpeg?h=200)


加上参数后 URL:[**https://demo.bitiful.com/girl.jpeg? w=200 & h=200**](https://demo.bitiful.com/girl.jpeg?w=200\&h=200)

加上参数后 URL:[**https://demo.bitiful.com/girl.jpeg? w=200 & h=200 & mode=clip**](https://demo.bitiful.com/girl.jpeg?w=200\&h=200\&mode=clip)

加上参数后 URL:[**https://demo.bitiful.com/girl.jpeg? w=200 & h=200 & dpr=0.5**](https://demo.bitiful.com/girl.jpeg?w=200\&h=200\&dpr=0.5)

加上参数后 URL:[**https://demo.bitiful.com/girl.jpeg? w=200 & h=200 & pos=top**](https://demo.bitiful.com/girl.jpeg?w=200\&h=200\&pos=top)

加上参数后 URL:[**`https://demo.bitiful.com/girl.jpeg? w=200 & h=200 & pos=bottom`**](https://demo.bitiful.com/girl.jpeg?w=200\&h=200\&pos=bottom)

加上参数后 URL:[**`https://demo.bitiful.com/girl.jpeg? w=200 & h=200 & pos=auto`**](https://demo.bitiful.com/girl.jpeg?w=200\&h=200\&pos=auto)

# 图像锐化
Source: https://bitiful-docs.mintlify.app/coreix/features/sharp
图像锐化参数为 sharp,可提高图片处理后的清晰度。
## 参数说明
该方法只能用于静态图片
### 相关参数总览
| 参数 | 含义 | 作用说明 |
| :------ | ------------ | -------------------------------------------------------------------------- |
| `sharp` | 指定**锐化效果强度** | - 取值范围:
0 \~ 500(默认为 0)
- 取值含义:取值越大,锐化强度越高,图片越清晰,但过大的值可能会导致图片失真。 |
### 效果演示
原始清晰度:

清晰度设置为 200:[https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&q=90 **`&sharp=200`**](https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&q=90\&sharp=200)

清晰度设置为 500:[https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&q=90 **`&sharp=500`**](https://demo.bitiful.com/girl.jpeg?rect=0,0,1000,1000\&w=300\&q=90\&sharp=500)

# 修剪边框
Source: https://bitiful-docs.mintlify.app/coreix/features/trim
## 概览
`trim` 用于自动去除图像四周的 **纯色边框**(如商品图的白底留白、截图的灰底)或 **透明边框** (如 PNG 导出时多余的透明画布)。它检测内容的最小外接矩形,然后把图裁到这个矩形。
为准确回应 `w/h/rect/dpr` 等 **会更改图片大小、比例 等参数** 的输出图片尺寸预期,该参数发生在所有此类处理之前。
| 模式 | 判定谓词 |
| ------------------ | ------------------------------------------------- |
| `color` | 像素与指定色的差 ≤ `trim-tol` → 背景 |
| `auto` | 行/列离自动检测背景色的均值差 ≤ `trim-md` 且标准差 ≤ `trim-sd` → 背景 |
| `alpha` | `alpha ≤ trim-alpha` → 背景 |
| `colorunlessalpha` | 有 alpha 通道时同 `alpha`,否则同 `auto` |
## 参数总表
| 参数 | 默认值 | 取值范围 | 生效模式 | 一句话含义 |
| ------------ | -------- | -------------------------------------------------- | ------- | --------------- |
| `trim` | 无(不修剪) | `auto` \| `color` \| `alpha` \| `colorunlessalpha` | — | 模式开关,不传则整个功能不激活 |
| `trim-color` | 无(=自动检测) | `RGB` / `RRGGBB` 十六进制 | `color` | 要裁掉的背景色 |
| `trim-tol` | `10` | `0` \~ `255` | `color` | 颜色容差 |
| `trim-md` | `11` | `0` \~ `255` | `auto` | 均值差阈值 |
| `trim-sd` | `10` | `0` \~ `255` | `auto` | 标准差阈值 |
| `trim-alpha` | `0` | `0` \~ `255` | `alpha` | 透明度阈值 |
**参数不通用**:
* `trim-tol` 只在 `color` 模式生效
* `trim-md`/`trim-sd` 只在 `auto` 模式生效
* `trim-alpha` 只在 `alpha` 模式生效。传给不匹配模式的参数会被静默忽略。
## 场景实例
### 修剪视频截帧
原图(上下带黑边)

`trim=auto` 自动修剪后

### 修剪 Logo / Icon
原图(四周带白边)

`trim=auto` 自动修剪后

***
## 参数详解
### `trim` —— 模式开关
不传该参数时不做任何修剪。四个可选值:
#### `auto`(推荐默认)
自动检测背景色(取**四角 8×8 小块的中位数**,对少量噪声与 JPEG 块效应鲁棒), 再按**行/列统计**判定背景边:某行/列同时满足「离背景的平均差 ≤ `trim-md`」且 「内部差异的标准差 ≤ `trim-sd`」才判为背景。
适用:照片留白、扫描件、带轻微压缩噪声或渐变的背景边。统计判定比逐像素匹配更鲁棒。
#### `color`
裁掉指定色 `trim-color` ±`trim-tol` 容差的边。若未提供 `trim-color`,回退为自动检测背景色。
适用:明确知道背景色是什么(如统一白底商品图),需要精确控制容差的场景。
#### `alpha`
裁掉 `alpha ≤ trim-alpha` 的透明边。**源图无 alpha 通道时为空操作**(原样返回,不报错)。
适用:PNG/WebP 等带透明通道的图,去掉多余的透明画布。
#### `colorunlessalpha`
智能选择:源图**含 alpha 通道**时走 `alpha`,否则走 `auto`。
适用:不确定输入是什么格式的通用场景(如用户上传的混合素材)。
***
### `trim-color` —— 背景色
* **默认**:无(回退自动检测)
* **格式**:十六进制,支持 3 位 `RGB` 缩写或 6 位 `RRGGBB`,可带 `#` 前缀
* **示例**:`fff`、`ffffff`、`e9e9e9`、`%23e9e9e9`(URL 中 `#` 需转义)
* **生效模式**:`color`
指定要裁掉的背景色。格式非法时会记警告并回退为自动检测,不会导致请求失败。
***
### `trim-tol` —— 颜色容差
* **默认**:`10`
* **范围**:`0` \~ `255`
* **生效模式**:`color`
像素与背景色**任一通道**之差 ≤ 该值即视为背景。
* **调小**(如 `0`\~`5`):只裁掉与背景色几乎完全一致的像素。适合合成图的绝对平整背景。
* **调大**(如 `20`\~`40`):容忍压缩噪声与轻微色偏。但过大会误裁接近背景色的浅色内容。
> 背景**绝对平整**时(如设计稿导出),容差取值不敏感——实测某图 `trim-tol` 从 5 到 40 结果只差 1px,因为内容与背景对比强烈,阈值落在哪都是同一条分界线。真正吃容差的是 「接近背景色的浅色内容」或「脏边」。
***
### `trim-md` —— 均值差阈值
* **默认**:`11`
* **范围**:`0` \~ `255`
* **生效模式**:`auto`
某行/列离背景色的**平均差** ≤ 该值,才**可能**判为背景边。管的是「整体偏移」—— 背景渐变、镜头暗角、整体色偏。
* **调小**:要求背景边更接近检测出的参考色,判定更严格(裁得更保守)。
* **调大**:容忍更明显的渐变背景(裁得更激进)。
***
### `trim-sd` —— 标准差阈值
* **默认**:`10`
* **范围**:`0` \~ `255`
* **生效模式**:`auto`
某行/列内部差异的**标准差** ≤ 该值,才**可能**判为背景边。管的是「内部起伏」—— 噪点、纹理、细节。
* **调小**:要求背景边内部更均匀(裁得更保守)。
* **调大**:容忍更多噪声(裁得更激进)。
> **`trim-md` 与 `trim-sd` 是「与」关系**:两个条件**同时满足**才判为背景行/列。 两者分工互补——均值差管整体偏移,标准差管内部起伏。一条有明显渐变但很平滑的边 会被 `trim-md` 拦下;一条整体色对但满是噪点的边会被 `trim-sd` 拦下。
***
### `trim-alpha` —— 透明度阈值
* **默认**:`0`
* **范围**:`0` \~ `255`
* **生效模式**:`alpha`
alpha **大于**该值才算内容。缺省 `0` 表示只要**非全透明**(alpha ≥ 1)就是内容。
* **默认 `0`**:**保守且安全**——所有半透明像素(羽化、投影、渐隐等艺术效果) 全部保留,只裁掉完全透明(alpha = 0)的边。
* **调大**(如 `8`):用于某些导出工具在「本应全透明」的边上留下 alpha=1\~2 噪声残渣 的情况。属于用户显式选择。
> trim 是**纯裁剪操作**,只裁掉矩形边缘,**不修改任何被保留的像素**。 半透明内容不会因 trim 而改变透明度。
***
## 管线次序
**trim 位于所有可能改变尺寸的处理之前**:
```text theme={null}
frame seek → trim → 百分比换算 → rect → resize → sharpen/blur → rotate → 水印 → 编码输出
↑
在这里去边
```
两个直接后果:
1. **后续操作都作用在裁剪后的图上**。`trim=auto&w=300` 是「先去边,再按去边后的宽高比缩到 300」。
2. **百分比参数以裁后尺寸为基准**。`trim=auto&w=50%` 中的 50% 是裁剪后宽度的一半, 不是原图宽度的一半。`rect=10%,10%,80%,80%` 同理。
# 文字水印
Source: https://bitiful-docs.mintlify.app/coreix/features/watermark
本文介绍为图片增加 **文字水印** 功能的参数说明及使用示例。
以下例子中,默认原图均为: [https://demo.bitiful.com/bridge.jpeg](https://demo.bitiful.com/bridge.jpeg)
## 参数说明
该方法只能用于静态图片
### 相关参数总览
\*\*水印参数: \*\*
| 参数 | 含义 | 作用说明 | 范围 |
| :---------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| `txt` | **水印内容** | 默认为空 - 代表不增加文字水印(推荐进行 UrlEncode) | 可打印字符 |
| `txt-font` | **水印字体** | 默认为空, 多个字体用半角逗号隔开, 系统按顺序匹配 | Inter,
NotoSansSC,
NotoSansTC,
SmileySans |
| `txt-size` | **水印字号大小** | - **\< 1** 时: 表示按原图最小边像素**百分比**自动计算字号
- **≥ 1** 时: 表示按 px 绝对值设定字号 | - |
| `txt-weight` | **水印字号粗细** | 同 CSS 中 font-weight,默认: 400 | 100 \~ 900 |
| `txt-line-height` | **水印行高** | 按**倍数**设置行高,同 CSS 中 line-height(不支持px),默认: 1.1 | 0.0 \~ 100.0 |
| `txt-pos` | **水印位置偏移** | - **≥ 1** 时: 表示按绝 px 对值设定偏移
- **\< 1** 时: 表示按原图像素**百分比**自动计算偏移(支持 3 种偏移策略)
-- 策略A: `0.99,0.99`表示按水印渲染范围的**最远边**
(即: **右&下**边)计算(此时水印绝对不会超过原图边界)
-- 策略B: `*0.99,*0.99`表示按水印渲染范围的**中心**计算
(此时水印会超出原图边界一半)
- 策略C: `**0.99,**0.99`表示按水印渲染范围的**最近边**
(即: **左&上**边)计算(此时水印会完全超出原图边界) | - |
| `txt-pct` | **水印最大百分比** | - 当水印 size 过大时,系统会用该值对总大小进行约束
如: 设定 0.5 代表无论 size 多大都不会超过原图 50%
大于 1 时代表可超出原图大小,有助于部分艺术表达场景 | 0.0 \~ 2.0 |
| `txt-color` | **水印颜色** | RGB 颜色 16 进制值,不支持颜色名称(默认为白色)
多个颜色用半角逗号(,)隔开,可**txt-color-deg**方向实现渐变色 | 000000
\~
FFFFFF |
| `txt-color-deg` | **水印颜色渐变方向** | 代表代表渐变角度(默认为 90 代表从 左 -> 右) | 0 \~ 360 |
| `txt-alpha` | **水印透明度** | 透明度百分比。 | 0.0 \~ 1.0 |
| `txt-shad` | **水印阴影虚化度** | - 为像素 px 绝对值
- **注意**: txt-color 为多个颜色适合,阴影**自动关闭** | 0 \~ 50 |
| `txt-shad-pos` | **水印阴影偏移** | 为像素 px 绝对值 | 0 \~ 100 |
| `txt-shad-color` | **水印阴影颜色** | - RGB 颜色 16 进制值,不支持颜色名称(默认为灰色)
- 注意: 不支持多个颜色 | 000000
\~
FFFFFF |
| `txt-hdr-rate` | **水印亮度** | - 支持 `1.0 ~ 3.0 的绝对值` 和 `0% ~ 100% 的百分比`两种参数
- 注意: 仅支持 HDR GainMap | 1.0 \~ 3.0
0% \~ 100% |
推荐: 为 txt-size 和 txt-pos 设定**比例值**而不是绝对值。
由于原图的比例、大小(特别是在配合 **w** 和 **h** 参数对原图进行裁剪、缩略后)各不相同,为 **txt-size** 和 **txt-pos** 设定 **小于 1 的比例值** 能让水印大小及偏移位置更可靠。
## 参数示例
加上参数后 URL: [https://demo.bitiful.com/bridge.jpeg? **`txt=Bitiful`**](https://demo.bitiful.com/bridge.jpeg?txt=Bitiful\&fmt=png)

加上参数后 URL: [https://demo.bitiful.com/bridge.jpeg?txt=Bitiful& **`txt-size=0.55 & txt-pos=0.5,*0.96 & txt-alpha=0.03`**](https://demo.bitiful.com/bridge.jpeg?txt=Bitiful\&txt-size=0.55\&txt-pos=0.5,*0.96\&txt-alpha=0.03\&fmt=png)

> 将图片模糊是为了更好地观察水印
> 加上参数后 URL: [https://demo.bitiful.com/bridge.jpeg?txt=Bitiful\&blur=50& **`txt-size=0.3 & txt-pos=0.5,*0.5 & txt-color=03FF76,FFE05B,03FFFE`**](https://demo.bitiful.com/bridge.jpeg?blur=50\&txt=Bitiful\&txt-size=0.3\&txt-pos=0.5,0.5\&txt-color=03FF76,FFE05B,03FFFE\&fm=png)
> 
# 图片水印
Source: https://bitiful-docs.mintlify.app/coreix/features/watermark-image
本文介绍为图片增加 图片水印 功能的参数说明及使用示例。
以下例子中,默认原图均为:[https://demo.bitiful.com/bridge.jpeg](https://demo.bitiful.com/bridge.jpeg)
## 参数说明
该方法只能用于静态图片
2025年7月起 支持 SVG 格式作为水印图源
### 相关参数总览
**图片水印格式支持:**
`SVG` / `JPG` / `PNG` / `WEBP` / `AVIF` / `HEIF` / `GIF`
**图片水印参数:**
| 参数 | 含义 | 作用说明 | 范围 |
| :----------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
| `mark` | **水印图片路径** | 桶内水印图片 path(如:*img/logo.png*)
默认为空 - 代表不增加图片水印(推荐进行 UrlEncode) | 只能是该桶内的图片 |
| `mark-pos` | **水印位置偏移** | - **≥ 1** 时: 表示按绝 px 对值设定偏移
- **\< 1** 时: 表示按原图像素**百分比**自动计算偏移(支持 3 种偏移策略)
-- 策略A: `0.99,0.99`表示按水印渲染范围的**最远边**
(即: **右&下**边)计算(此时水印绝对不会超过原图边界)
-- 策略B: `*0.99,*0.99`表示按水印渲染范围的**中心**计算
(此时水印会超出原图边界一半)
- 策略C: `**0.99,**0.99`表示按水印渲染范围的**最近边**
(即: **左&上**边)计算(此时水印会完全超出原图边界) | - |
| `mark-pct` | **水印最大百分比** | - 当水印图片 size 过大时,系统会用该值对总大小进行约束
- 如:设定 0.5 代表无论 size 多大都不会超过原图 50%
大于 1 时代表可超出原图大小,有助于部分艺术表达场景 | 0.0 \~ 2.0 |
| `mark-alpha` | **水印透明度** | 透明度百分比。 | 0.0 \~ 1.0 |
| `hdr-rate` | **HDR亮度** | - 支持 `1.0 ~ 3.0 的绝对值` 和 `0% ~ 100% 的百分比`两种参数
- 注意: 仅支持 HDR GainMap | 1.0 \~ 3.0
0% \~ 100% |
推荐:为 mark-pos 设定 **比例值** 而不是绝对值
由于原图的比例、大小(特别是在配合 **w** 和 **h** 参数对原图进行裁剪、缩略后)各不相同,为 **mark-pos** 设定 **小于 1 的比例值** 能让水印大小及偏移位置更可靠。
加上参数后 URL:[**`https://demo.bitiful.com/bridge.jpeg? mark=static/img/bitiful-logo@3x.png & fm=png & mark-pos=0.5,0.95`**](https://demo.bitiful.com/bridge.jpeg?mark=static/img/bitiful-logo@3x.png\&fm=png\&mark-pos=0.5,0.95\&fmt=png)

# HDR 图片和视频
Source: https://bitiful-docs.mintlify.app/coreix/hdr
CoreIX 支持 HDR 图片和视频。
## HDR 介绍
百度百科 HDR 介绍:[https://baike.baidu.com/item/HDR/2863820](https://baike.baidu.com/item/HDR/2863820)
两颗皮蛋介绍 iPhone HDR:[https://www.bilibili.com/video/BV1V14y1R7Rk/](https://www.bilibili.com/video/BV1V14y1R7Rk/)
目前包括华为、苹果、小米、OPPO 等旗舰机型都已支持 HDR 照片和视频的拍摄录制,但除了各大主流视频 APP 之外,大多社交 APP 对 HDR 视频的支持都不好,更不要说 HDR 照片。
## CoreIX HDR 支持范围
### 支持功能
1. **HDR 视频截图**:系统若判断当前视频为 HDR 格式,则截出来的图片默认也带 HDR 效果(JPEG、PNG、Webp、Avif);
2. **HDR 照片处理**:HDR 照片支持所有的 裁剪、缩略图、压缩、格式转换 等操作;
3. **HDR 映射为 SDR**:若将 cs 参数(ColorSpace)设置为 srgb 或 sdr,则系统会讲 HDR 图片映射为普通 RGB 效果,避免出现灰图。
## HDR 演示
### HDR 视频截图:
最佳 HDR 浏览方案:
* 支持 `HDR 600+` 峰值亮度的显示设备,如:Apple Silicon MacBook Pro 16'、LG - 32GQ950
* 支持 `HDR10` 和 `杜比视界` 的浏览器,如:Google Chrome 100+
| HDR 资源 | CoreIX 截图默认输出 HDR | CoreIX 截图强转 SDR | 阿里云 OSS 丢失色彩和方向 |
| :----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [彩虹.mov (iPhone 录制)](https://demo.bitiful.com/hdr-img/rainbow.mov) | ![rainbow.mov.hdr.jpg]()
[查看大图](https://demo.bitiful.com/hdr-img/rainbow.mov?frame=5000\&w=2000) | ![rainbow.mov.sdr.jpg]()
[查看大图](https://demo.bitiful.com/hdr-img/rainbow.mov?frame=5000\&w=2000\&hdr-rate=0) | ![rainbow.mov.oss.jpg]()
[查看大图](https://oss.ladydaily.com/hdr-img/rainbow.mov?x-oss-process=video/snapshot,t_4950,f_jpg,scaletype_crop,w_2000) |
| [食物.mov (iPhone 录制)](https://demo.bitiful.com/hdr-img/foods.mov) | ![foods.mov.hdr.jpg]()
[查看大图](https://demo.bitiful.com/hdr-img/foods.mov?frame=5000\&w=2000) | ![foods.mov.sdr.jpg]()
[查看大图](https://demo.bitiful.com/hdr-img/foods.mov?frame=5000\&w=2000\&hdr-rate=0) | ![foods.mov.oss.jpg]()
[查看大图](https://oss.ladydaily.com/hdr-img/foods.mov?x-oss-process=video/snapshot,t_4950,f_jpg,scaletype_crop,w_2000) |
2026 年 6 月起:HDR 处理支持最高 **16 bit** 色深输出
# S4 静态CDN API
Source: https://bitiful-docs.mintlify.app/developer/api/cdn
介绍缤纷云 S4 的静态 CDN API。
## 获取控制台 API Token
前往控制台获取:[https://console.bitiful.com/apiToken](https://console.bitiful.com/apiToken)
## 流量
**参数说明**
**start\_time** - 起始时间, timestamp, 秒
**end\_time** - 截止时间, timestamp, 秒
**period** - 统计宽度, hourly / daily / monthly 3 个值可选
### 边缘流量
```shell theme={null}
curl --get -H "Authorization: {API Token from: https://console.bitiful.com/apiToken}" "https://api.bitiful.com/cdn/data/{cdn-domain}/traffic?start_time={start_time}&end_time={end_time}&period={period}"
```
### 回源流量
```shell theme={null}
curl --get -H "Authorization: {API Token from: https://console.bitiful.com/apiToken}" "https://api.bitiful.com/cdn/data/{cdn-domain}/traffic_origin?start_time={start_time}&end_time={end_time}&period={period}"
```
## 请求
**参数说明**
**start\_time** 起始时间, timestamp, 秒
**end\_time** 截止时间, timestamp, 秒
**period** 统计宽度, hourly / daily / monthly 3 个值可选
### 边缘请求数
```shell theme={null}
curl --get -H "Authorization: {API Token from: https://console.bitiful.com/apiToken}" "https://api.bitiful.com/cdn/data/{cdn-domain}/request?start_time={start_time}&end_time={end_time}&period={period}"
```
### 回源请求数
```shell theme={null}
curl --get -H "Authorization: {API Token from: https://console.bitiful.com/apiToken}" "https://api.bitiful.com/cdn/data/{cdn-domain}/request_origin?start_time={start_time}&end_time={end_time}&period={period}"
```
## CDN 实时日志
仅支持 3 天内日志
**参数说明**
**start\_time** 起始时间,timestamp,纳秒,用作分页,例如:1723046499000000000
**codes** 过滤 httpcode. 2XX / 3XX / 4XX / 5XX / ALL 选其一,默认为 ALL
**limit** 一次性返回条数,最大值 1000
```shell theme={null}
curl -H "Authorization: {API Token from: https://console.bitiful.com/apiToken}" "https://api.bitiful.com/cdn/data/{cdn-domain}/logs?start_time={start_time}&codes={codes}&limit={limit}"
```
## CDN 刷新缓存
**请求说明**
Method: POST
Content-Type: application/json
**参数说明**
**type** 刷新类型,值为 url 或者 directory, 分别代表 刷新url 和 刷新目录
**url\_list** 类型为字符串数组, 刷新的url/目录列表, 数组中元素数量不大于20, URL不能包含星号字符'\*'. 如果URL中的目录或文件名包含'%'等特殊符号, 需要先进行URL编码.
```shell theme={null}
curl -X POST -H "Authorization: {API Token from: https://console.bitiful.com/apiToken}" "https://api.bitiful.com/cdn/cache/refresh" -d '{"type": "url", "url_list": ["https://xxx.com/yyy/zzz.png", "https://aaa.com/bbb/ccc.png"]}'
```
# S4 证书 API
Source: https://bitiful-docs.mintlify.app/developer/api/certs
介绍缤纷云证书中心的 API。
## 获取控制台 API Token
前往控制台获取:[https://console.bitiful.com/apiToken](https://console.bitiful.com/apiToken)
## 获取证书列表
暂无任何参数
**请求示例**:
```shell theme={null}
curl -H "Authorization: {API Token from: https://console.bitiful.com/apiToken}" "https://api.bitiful.com/cert/list"
```
## 证书内容获取
最佳实践
在自有架构中定时运行 **证书内容获取 API** 并结合部署相关脚本,可以做到全局 **自动应用最新的域名证书**。
暂无任何参数
**请求示例**:
```shell theme={null}
curl -H "Authorization: {API Token from: https://console.bitiful.com/apiToken}" "https://api.bitiful.com/cert/data//content"
```
**返回示例**:
```json theme={null}
// curl -H "Authorization: {API-Token}" "https://api.bitiful.com/cert/data/usercontents.somecdn.com-rsa-auto/content"
{
"crt": "-----BEGIN CERTIFICATE-----\n<证书内容>\n-----END CERTIFICATE-----",
"key": "-----BEGIN PRIVATE KEY-----\n<私钥内容>\n-----END PRIVATE KEY-----",
"auto": true //是否自动证书
}
```
在自动获取证书的工作流中,请注意配合安全措施 **防止 API-Token 泄露**。
## 证书添加
**请求示例**:
```shell theme={null}
curl --request POST 'https://api.bitiful.com/cert/add' \
-H 'Authorization: {API Token from: https://console.bitiful.com/apiToken}' \
-H 'Content-Type: application/json' \
--data-raw '{
"cert_name": "证书名称",
"cert_private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
"cert_content": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
}'
```
# S4 对象存储 API
Source: https://bitiful-docs.mintlify.app/developer/api/s4
介绍缤纷云 S4 的 API。
## 获取控制台 API Token
前往控制台获取:[https://console.bitiful.com/apiToken](https://console.bitiful.com/apiToken)
## 容量、文件数
暂无任何参数
```shell theme={null}
curl -H "Authorization: {API Token from: https://console.bitiful.com/apiToken}" "https://api.bitiful.com/s4/data/{bucket-name}/usage"
```
## S4 实时日志
仅支持 3 天内日志
**参数说明**
**start\_time** 起始时间,timestamp,纳秒,用作分页,例如:1723046499000000000
**codes** 过滤 httpcode,2XX / 3XX / 4XX / 5XX / ALL 选其一,默认为 ALL
**limit** 一次性返回条数,最大值 1000
```shell theme={null}
curl --get -H "Authorization: {API Token from: https://console.bitiful.com/apiToken}" "https://api.bitiful.com/s4/data/{bucket-name}/logs?start_time={start_time}&codes={codes}&limit={limit}"
```
# 用 Aws-Android-SDK 连接 S4
Source: https://bitiful-docs.mintlify.app/developer/sdk/android-demo/start-to-use
本文介绍如何用 Aws-Android-SDK 连接 缤纷云 S4。
## 引入 aws-for-android 框架
我们强烈建议 `不要在` 客户端中内置 ak / sk,也 `不要用` API 下发 ak / sk。
更优方案请参考我们的:《[上传内容最佳实践](/best-practice/web-uploads)》
前置步骤:安装 sdk([https://github.com/aws-amplify/aws-sdk-android](https://github.com/aws-amplify/aws-sdk-android) )
```java s4-demo.android.java theme={null}
def aws_version = '2.64.0'
implementation "com.amazonaws:aws-android-sdk-s3:$aws_version"
implementation ("com.amazonaws:aws-android-sdk-mobile-client:$aws_version")
```
### 连接到 S4 Endpoint
```java title="s4-demo.java" theme={null}
fun getS3Client(): AmazonS3Client {
val credentials = object: AWSCredentials {
override fun getAWSAccessKeyId() = accessKey // 请到控制台创建子账户,并为子账户创建相应 accessKey
override fun getAWSSecretKey() = sercetKey // !!切记,创建子账户时,需要手动为其分配具体权限!!
}
val amazonS3Client = AmazonS3Client(credentials, Region.getRegion(Regions.DEFAULT_REGION), ClientConfiguration())
amazonS3Client.endpoint = "https://s3.bitiful.net" // 请填入控制台 “Bucket 设置” 页面底部的 “Endpoint” 标签中的信息
return amazonS3Client
}
```
### 列出桶中对象
```java s4-demo.android.java theme={null}
val s3 = getS3Client()
s3.listObjects(bucketName)
```
### 获取具备时效的预签名文件下载链接
```java s4-demo.android.java theme={null}
val s3 = getS3Client()
val url = s3.generatePresignedUrl(bucketName, key, date)
```
# 用 Aws-SDK-Go-v2 连接 S4
Source: https://bitiful-docs.mintlify.app/developer/sdk/golang-demo/start-to-use
本文介绍如何用 aws-sdk-go-v2 连接 缤纷云 S4。
## 连接到 S4 Endpoint
### 以下代码基于版本
```
github.com/aws/aws-sdk-go-v2 v1.24.1
github.com/aws/aws-sdk-go-v2/config v1.26.6
github.com/aws/aws-sdk-go-v2/credentials v1.16.16
github.com/aws/aws-sdk-go-v2/service/s3 v1.48.1
```
```go main.go theme={null}
package main
import (
"context"
"fmt"
"log"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
const s3Endpoint = "https://s3.bitiful.net"
func main() {
// 替换成自己的AccessKey和SecretKey
s3AccessKey := "your-access-key"
s3SecretKey := "your-secret-key"
// 获取S3客户端
s3Client, err := getS3Client(s3AccessKey, s3SecretKey)
if err != nil {
log.Println("get s3 client failed, err=", err)
return
}
log.Println("get s3 client success", s3Client)
}
// 获取S3客户端
func getS3Client(key, secret string) (*s3.Client, error) {
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
if service == "S3" {
return aws.Endpoint{
URL: s3Endpoint,
}, nil
}
return aws.Endpoint{}, fmt.Errorf("unknown service requested")
})
customProvider := credentials.NewStaticCredentialsProvider(key, secret, "")
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithCredentialsProvider(customProvider), config.WithEndpointResolverWithOptions(customResolver))
if err != nil {
return nil, err
}
cfg.Region = "cn-east-1"
s3client := s3.NewFromConfig(cfg)
return s3client, nil
}
```
### 列出桶中对象
```go main.go theme={null}
package main
import (
"context"
"fmt"
"log"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
const s3Endpoint = "https://s3.bitiful.net"
func main() {
// 替换成自己的AccessKey和SecretKey
s3AccessKey := "your-access-key"
s3SecretKey := "your-secret-key"
// 获取S3客户端
s3Client, err := getS3Client(s3AccessKey, s3SecretKey)
if err != nil {
log.Println("get s3 client failed, err=", err)
return
}
// 替换成自己的桶名
bucket := "your-bucket-name" // 例如:test
// 获取桶内文件列表
listObjsResponse, err := s3Client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input{
Bucket: aws.String(bucket),
Delimiter: aws.String("/"),
MaxKeys: aws.Int32(50),
})
if err != nil {
log.Println("list objects failed, err=", err)
return
}
// 输出文件列表
for _, object := range listObjsResponse.Contents {
log.Printf("object key=%v", *object.Key)
}
log.Println("list objects success")
}
// 获取S3客户端
func getS3Client(key, secret string) (*s3.Client, error) {
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
if service == "S3" {
return aws.Endpoint{
URL: s3Endpoint,
}, nil
}
return aws.Endpoint{}, fmt.Errorf("unknown service requested")
})
customProvider := credentials.NewStaticCredentialsProvider(key, secret, "")
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithCredentialsProvider(customProvider), config.WithEndpointResolverWithOptions(customResolver))
if err != nil {
return nil, err
}
cfg.Region = "cn-east-1"
s3client := s3.NewFromConfig(cfg)
return s3client, nil
}
```
### 获取具备时效的预签名文件下载链接
```go main.go theme={null}
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
const s3Endpoint = "https://s3.bitiful.net"
func main() {
// 替换成自己的AccessKey和SecretKey
s3AccessKey := "your-access-key"
s3SecretKey := "your-secret-key"
// 获取S3客户端
s3Client, err := getS3Client(s3AccessKey, s3SecretKey)
if err != nil {
log.Println("get s3 client failed, err=", err)
return
}
// 替换成自己的桶名和对象的key
bucket := "your-bucket-name" // 例如:test
objectKey := "your-object-key" // 例如:test.txt
// 获取 presign client
preSignClient := s3.NewPresignClient(s3Client)
// 获取预签名请求
preSignedRequest, _ := preSignClient.PresignGetObject(context.TODO(), &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(objectKey),
}, func(presignOptions *s3.PresignOptions) {
presignOptions.Expires = time.Hour // 过期时间,默认是900秒,这里修改为合适的时效,比如1小时
})
// 输出预签名URL
preSignedUrl := preSignedRequest.URL
log.Printf("get preSigned url success, preSignedUrl=%v", preSignedUrl)
}
// 获取S3客户端
func getS3Client(key, secret string) (*s3.Client, error) {
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
if service == "S3" {
return aws.Endpoint{
URL: s3Endpoint,
}, nil
}
return aws.Endpoint{}, fmt.Errorf("unknown service requested")
})
customProvider := credentials.NewStaticCredentialsProvider(key, secret, "")
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithCredentialsProvider(customProvider), config.WithEndpointResolverWithOptions(customResolver))
if err != nil {
return nil, err
}
cfg.Region = "cn-east-1"
s3client := s3.NewFromConfig(cfg)
return s3client, nil
}
```
### 在预签名链接中加入 CoreIX 媒体处理参数
因 S3 协议的预签名会将所有 Url 参数(Args)包含在内统一做签名,所以这里需要用到 Middleware 处理:
```go main.go theme={null}
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/aws/smithy-go/middleware"
smithyhttp "github.com/aws/smithy-go/transport/http"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
const s3Endpoint = "https://s3.bitiful.net"
func main() {
// 替换成自己的AccessKey和SecretKey
s3AccessKey := "your-access-key"
s3SecretKey := "your-secret-key"
// 获取S3客户端
s3Client, err := getS3Client(s3AccessKey, s3SecretKey)
if err != nil {
log.Println("get s3 client failed, err=", err)
return
}
// 替换成自己的桶名和对象的key
bucket := "your-bucket-name" // 例如:test
objectKey := "your-object-key" // 例如:test.txt
// 获取 presign client
preSignClient := s3.NewPresignClient(s3Client)
// 在预签名地址中 加入 CoreIX 媒体处理参数
bitifulQuery := map[string]string{"w": "500"} // 宽度为500px
// 在预签名地址中 加入「单线程限速」参数
// bitifulQuery := map[string]string{"x-amz-limit-rate": "102400"} // 102400 代表 102400字节/秒
//自定义参数, 使用ctx传递
ctx := context.WithValue(context.TODO(), "bitiful-query", bitifulQuery)
// 获取预签名请求
preSignedRequest, _ := preSignClient.PresignGetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(objectKey),
}, func(presignOptions *s3.PresignOptions) {
presignOptions.Expires = time.Hour // 过期时间,默认是900秒,这里修改为合适的时效,比如1小时
presignOptions.ClientOptions = append(presignOptions.ClientOptions, func(options *s3.Options) {
// 注入自定义中间件
options.APIOptions = append(options.APIOptions, registerPresignedUrlAddBitifulQueryMiddleware)
})
})
//输出预签名URL
preSignedUrl := preSignedRequest.URL
log.Println("get preSigned url success, preSignedUrl=", preSignedUrl)
}
// 获取S3客户端
func getS3Client(key, secret string) (*s3.Client, error) {
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
if service == "S3" {
return aws.Endpoint{
URL: s3Endpoint,
}, nil
}
return aws.Endpoint{}, fmt.Errorf("unknown service requested")
})
customProvider := credentials.NewStaticCredentialsProvider(key, secret, "")
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithCredentialsProvider(customProvider), config.WithEndpointResolverWithOptions(customResolver))
if err != nil {
return nil, err
}
cfg.Region = "cn-east-1"
s3client := s3.NewFromConfig(cfg)
return s3client, nil
}
// 获取预签名url增加自定义参数
func registerPresignedUrlAddBitifulQueryMiddleware(stack *middleware.Stack) error {
// Attach the custom middleware to the beginning of the Initialize step
return stack.Build.Add(presignedUrlAddBitifulQueryMiddleware, middleware.After)
}
// 自定义中间件
var presignedUrlAddBitifulQueryMiddleware = middleware.BuildMiddlewareFunc("AddBitifulQuery", func(ctx context.Context, input middleware.BuildInput, next middleware.BuildHandler) (out middleware.BuildOutput, metadata middleware.Metadata, err error) {
bitifulQuery := ctx.Value("bitiful-query")
if bitifulQuery == nil {
return next.HandleBuild(ctx, input)
}
req, ok := input.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, fmt.Errorf("unknown transport type %T", req)
}
bitifulQueryMap, ok := bitifulQuery.(map[string]string)
if !ok {
return next.HandleBuild(ctx, input)
}
// set bitiful query
query := req.URL.Query()
for key, value := range bitifulQueryMap {
query.Set(key, value)
}
req.URL.RawQuery = query.Encode()
return next.HandleBuild(ctx, input)
})
```
### 在预签名链接中加入「单线程限速」参数
S4 拓展了 x-amz-limit-rate 参数,可以对当前对象做下载的单线程限速,value 为 字节数(正整数)。
如上所述,这里仍然需要用到 Middleware 处理签名, 参考【在预签名链接中加入 CoreIX 媒体处理参数】只需修改bitifulQuery即可:
```
...
// 在预签名地址中 加入「单线程限速」参数
bitifulQuery := map[string]string{"x-amz-limit-rate": "102400"} // 102400 代表 102400字节/秒
//自定义参数, 使用ctx传递
ctx := context.WithValue(context.TODO(), "bitiful-query", bitifulQuery)
...
```
# SDK 概述
Source: https://bitiful-docs.mintlify.app/developer/sdk/intro
本章介绍使用 S3 SDK 接入缤纷云 S4 服务。
S4 对象存储兼容 [S3 协议](https://docs.aws.amazon.com/zh_cn/s3/),并有针对性加强。
## Amazon AWS S3
Amazon S3,全名为亚马逊简易存储服务(Amazon Simple Storage Service),是亚马逊公司推出的 **最早** 的对象存储服务。其 S3 协议几乎是当今对象存储服务的 **事实标准**,拥有 **丰富的开发者资料** 及 **广泛的开发者生态**。
除了缤纷云 S4 之外,国内外众多公有云推出的对象存储服务几乎全都支持标准的 S3 协议。
例如:
* 国内的:[阿里云 OSS](https://help.aliyun.com/zh/oss/developer-reference/compatibility-with-amazon-s3-1/)、[腾讯云 COS](https://cloud.tencent.com/document/product/436/37421)、[七牛云 Koda](https://developer.qiniu.com/kodo/4086/aws-s3-compatible)
* 国外的:[AWS S3](https://aws.amazon.com/cn/s3/)、[Backblaze](https://www.backblaze.com/)、[Wasabi](https://wasabi.com/)、[Cloudflare R2](https://www.cloudflare.com/zh-cn/developer-platform/r2/)、[DigitalOcean](https://www.digitalocean.com/products/spaces)
**最佳实践建议:**
无论使用哪一个对象存储服务,我们都建议团队中统一使用 **S3 协议**。
不仅能天然避免供应商锁定,同时提升团队的开发效率,降低总体成本。
### 不同语言的 S3-SDK Demo:
> 服务端
利用 Golang 的 S3 SDK 接入缤纷云 S4 服务。
利用 PHP 的 S3 SDK 接入缤纷云 S4 服务。
利用 Python 3 的 S3 SDK 接入缤纷云 S4 服务。
利用 NodeJs 的 S3 SDK 接入缤纷云 S4 服务。
利用 Java 的 S3 SDK 接入缤纷云 S4 服务。
> 客户端
我们强烈建议 `不要在` 客户端中内置 ak / sk,也 `不要用` API 下发 ak / sk。
更优方案请参考我们的:《[上传内容最佳实践](/best-practice/web-uploads)》
利用 Javascript 的 S3 SDK 接入缤纷云 S4 服务。
利用 Swift 的 S3 SDK 接入缤纷云 S4 服务。
# 用 Aws-for-Java 连接 S4
Source: https://bitiful-docs.mintlify.app/developer/sdk/java-demo/start-to-use
本文介绍如何用 Aws-for-Java 连接 缤纷云 S4。
## 引入 aws-for-java 框架
前置步骤:安装 sdk([https://github.com/aws/aws-sdk-java-v2](https://github.com/aws/aws-sdk-java-v2) )
```java s4-demo.java theme={null}
implementation 'software.amazon.awssdk:s3:2.20.29'
```
### 连接到 S4 Endpoint
```java s4-demo.java theme={null}
fun getS3Client() = S3Client.builder().region(Region.CN_NORTH_1).endpointOverride(URI.create("https://s3.bitiful.net/"))// 请填入控制台 “Bucket 设置” 页面底部的 “Endpoint” 标签中的信息
.credentialsProvider(AwsCredentialsProvider {
return@AwsCredentialsProvider object :AwsCredentials{
override fun accessKeyId(): String {
return accessKey // 请到控制台创建子账户,并为子账户创建相应 accessKey
}
override fun secretAccessKey(): String {
return sercetKey // !!切记,创建子账户时,需要手动为其分配具体权限!!
}
}
}).build()
```
### 列出桶中对象
```java s4-demo.java theme={null}
val s3 = getS3Client()
s3.listObjects(ListObjectsRequest.builder().bucket(bucketName))
```
### 获取具备时效的预签名文件下载链接
```java s4-demo.java theme={null}
val presign = S3Presigner.builder().region(Region.CN_NORTH_1).endpointOverride(URI.create("https://s3.bitiful.net/"))// 请填入控制台 “Bucket 设置” 页面底部的 “Endpoint” 标签中的信息
.credentialsProvider(AwsCredentialsProvider {
return@AwsCredentialsProvider object :AwsCredentials{
override fun accessKeyId(): String {
return accessKey // 请到控制台创建子账户,并为子账户创建相应 accessKey
}
override fun secretAccessKey(): String {
return sercetKey // !!切记,创建子账户时,需要手动为其分配具体权限!!
}
}
}).build()
val request = GetObjectRequest.builder().bucket(bucketName).key(key).build()
val presignRequest = GetObjectPresignRequest.builder()
.signatureDuration(Duration.ofSeconds(time))
.getObjectRequest(request).build()
val url = presign.presignGetObject(presignRequest).url().toString()
```
# 用 Aws-for-PHP 连接 S4
Source: https://bitiful-docs.mintlify.app/developer/sdk/php-demo/start-to-use
本文介绍如何用 Aws-for-PHP 连接 缤纷云 S4。
## 引入 aws-for-php 框架
前置步骤:安装框架([https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/welcome.html](https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/welcome.html) )
```php s4-demo.php theme={null}
require 'vendor/autoload.php';
use Aws\Middleware;
use Aws\S3\S3Client;
use Aws\S3\S3ClientInterface;
use Aws\S3\MultipartUploader;
use Aws\Exception\AwsException;
use Aws\S3\Exception\S3Exception;
```
### 连接到 S4 Endpoint
```php s4-demo.php theme={null}
/**
*
* 使用 AWS S3 协议连接到 Bitiful S4 Endpoint
*
* @param - 桶名
* @return - S3Client 对象
*
*/
private function connectS4() {
$s3 = new Aws\S3\S3Client([
'credentials' => [
'key' => '子账户 accessKey', // 请到控制台创建子账户,并为子账户创建相应 accessKey
'secret' => '子账户 secretKey', // !!切记,创建子账户时,需要手动为其分配具体权限!!
],
'use_path_style_endpoint' => false,
'use_aws_shared_config_files' => false,
'endpoint' => "https://s3.bitiful.net", // 请填入控制台 “Bucket 设置” 页面底部的 “Endpoint” 标签中的信息
'signature_version' => 'v4',
'version' => 'latest',
'region' => 'cn-east-1'
]);
return $s3;
}
```
### 列出桶中对象
```php s4-demo.php theme={null}
/**
*
* List objects in the bucket
*
* @param - bucket name, prefix, delimiter
* @return - objects list
*
*/
public function listObjects($bucket, $prefix, $StartAfter) {
$s4 = $this->connectS4();
$objects = $s4->listObjects([
'Bucket' => $bucket,
'Prefix' => $prefix,
'Delimiter' => '/',
'StartAfter' => $StartAfter,
'MaxKeys' => 50
]);
return $objects;
}
```
### 获取具备时效的预签名文件下载链接
```php s4-demo.php theme={null}
/**
*
* 获取具备时效的预签名文件下载链接
*
* @param - Object Key, bucket name
* @return - 该对象时效性预签名链接
*
*/
public function getFileLink($key, $bucket) {
$s4 = $this->connectS4($bucket);
$key = html_entity_decode($key, ENT_COMPAT, 'UTF-8');
$result = $s4->getCommand('GetObject',[
'Bucket' => $bucket,
'Key' => $key
]);
# 用 S3 协议生成一个 S4 对象的预签名私有链接对象(未来 1 小时内有效)
$presigned_url = $s4->createPresignedRequest($result , '+1 hours');
# 获取预签名私有链接字符串并返回
$private_url = (string)$presigned_url->getUri();
return $private_url;
}
```
### 在预签名链接中加入 CoreIX 媒体处理参数
因 S3 协议的预签名会将所有 Url 参数(Args)包含在内统一做签名,所以这里需要用到 Middleware 处理:
```php s4-demo.php theme={null}
/**
*
* 获取具备时效的预签名文件下载链接
*
* @param - 需要下载的 Object Key、桶名
* @return - 该对象时效性预签名链接
*
*/
public function getFileLink($key, $bucket) {
$s4 = $this->connectS4($bucket);
$key = html_entity_decode($key, ENT_COMPAT, 'UTF-8');
$result = $s4->getCommand('GetObject',[
'Bucket' => $bucket,
'Key' => $key
]);
$result->getHandlerList()->appendBuild(
Middleware::mapRequest(function (RequestInterface $request) {
// Return a new request with the added header
return $request->withUri(
$request->getUri()->withQuery(
$request->getUri()->getQuery() . "w=500" // 这里在增加了一个 w=500 的 CoreIX 处理参数
)
);
}),
'add-custom-param'
);
# 这里将会 `w=500` 一起加入签名计算
$presigned_url = $s4->createPresignedRequest($result , '+1 hours');
# 获取预签名私有链接字符串并返回
$private_url = (string)$presigned_url->getUri();
return $private_url;
}
```
### 在预签名链接中加入「单线程限速」参数
S4 拓展了 x-amz-limit-rate 参数,可以对当前对象做下载的单线程限速,value 为 字节数(正整数)。
如上所述,这里仍然需要用到 Middleware 处理签名:
```php s4-demo.php theme={null}
/**
*
* 获取具备时效的预签名文件下载链接
*
* @param - 需要下载的 Object Key、桶名
* @return - 该对象时效性预签名链接
*
*/
public function getFileLink($key, $bucket) {
$s4 = $this->connectS4($bucket);
$key = html_entity_decode($key, ENT_COMPAT, 'UTF-8');
$result = $s4->getCommand('GetObject',[
'Bucket' => $bucket,
'Key' => $key
]);
$result->getHandlerList()->appendBuild(
Middleware::mapRequest(function (RequestInterface $request) {
// Return a new request with the added header
return $request->withUri(
$request->getUri()->withQuery(
$request->getUri()->getQuery() . "x-amz-limit-rate=102400" // 限 102400 字节(100 KiB)每秒
)
);
}),
'add-custom-param'
);
# 这里将会 `x-amz-limit-rate=102400` 一起加入签名计算
$presigned_url = $s4->createPresignedRequest($result , '+1 hours');
# 获取预签名私有链接字符串并返回
$private_url = (string)$presigned_url->getUri();
return $private_url;
}
```
# 用 Python3-Boto3 连接 S4
Source: https://bitiful-docs.mintlify.app/developer/sdk/python3-demo/start-to-use
本文介绍如何用 Boto3 连接 缤纷云 S4。
## 引入 boto3 框架
前置步骤:安装框架([https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html) )
```python s4-demo.py theme={null}
# import
import boto3
from botocore.client import Config
# Config
s3endpoint = 'https://s3.bitiful.net' # 请填入控制台 “Bucket 设置” 页面底部的 “Endpoint” 标签中的信息
s3region = 'cn-east-1'
s3accessKeyId = '子账户 accessKey' # 请到控制台创建子账户,并为子账户创建相应 accessKey
s3SecretKeyId = '子账户 secretKey' # !!切记,创建子账户时,需要手动为其分配具体权限!!
```
### 连接到 S4 Endpoint
```python s4-demo.py theme={null}
s3client = boto3.client(
's3',
aws_access_key_id = s3accessKeyId,
aws_secret_access_key = s3SecretKeyId,
endpoint_url = s3endpoint,
region_name = s3region
)
```
### 列出桶中对象
```python s4-demo.py theme={null}
buckets = s3client.list_buckets()
for bucket in buckets['Buckets']:
print(bucket["Name"])
```
### 用 Python 调用 S3 SDK(Boto3)实现一个下发“PutObject 预签名链接”以供 Web JS(axios 发起 PUT 请求)上传的前后端完整例子:
```python s4-demo.py theme={null}
import boto3
from flask import Flask
from flask import render_template_string
from flask import request
app = Flask(__name__)
@app.get('/upload_url')
def get_upload_url():
# Config
s3endpoint = 'https://s3.bitiful.net' # 请填入控制台 “Bucket 设置” 页面底部的 “Endpoint” 标签中的信息
s3region = 'cn-east-1'
s3accessKeyId = '子账户 accessKey' # 请到控制台创建子账户,并为子账户创建相应 accessKey
s3SecretKeyId = '子账户 secretKey' # !!切记,创建子账户时,需要手动为其分配具体权限!!
# 连接 S3
client = boto3.client(
's3',
aws_access_key_id = s3accessKeyId,
aws_secret_access_key = s3SecretKeyId,
endpoint_url = s3endpoint,
region_name = s3region
)
url = client.generate_presigned_url(
'put_object',
Params={
'Bucket': 'xxxxxx',
'Key': request.args.get('key'),
},
ExpiresIn=3600
)
return {'url': url}
@app.get('/')
def index():
return render_template_string('''
S3 File Upload
S3 File Upload
''')
if __name__ == '__main__':
app.run(debug=True)
```
# 介绍
Source: https://bitiful-docs.mintlify.app/framerplus/intro
介绍 Framer+ 加速服务。

# 欠费说明
Source: https://bitiful-docs.mintlify.app/prices/arrearage
缤纷云产品欠费说明。
缤纷云产品均按照小时出账,出具账单后实时结算扣款。如果您的账户余额小于待结算的账单金额,会被认为欠费,您将会收到余额不足的短信或邮件提醒。
## 提醒策略
1. 当 **余额可能不足未来 1 天消耗** 时,会发送 **余额不足** 提醒短信,每 **4 小时** 发一次,最多发 3 次;
2. 当 **欠费** 时,会暂停所有服务,并发送 **服务暂停** 提醒短信,每 **6 小时** 发一次,最多发 4 次;
3. 当 **欠费超过 5 天** 时,会发送 **项目即将清空** 提醒短信,每 **6 小时** 发一次,最多发 8 次。
## 欠费后处理
### 对象存储
* 若欠费后,缤纷云会尽快暂停该账户下所有桶的对外访问权限,但仍保留您的数据,保留的数据仍占用存储空间资源,故欠费会累积;
* 如您在欠费后 31 天内仍未补齐欠款,则视为您主动放弃本服务,缤纷云将终止本产品服务条款,删除您在对象存储保存的所有数据并不可恢复。
### CDN
* 欠费后,缤纷云会尽快暂停该账户下所有 CDN 的对外访问权限
* 欠费后 31 天内若仍未补齐欠款,则视为您主动放弃本服务,缤纷云将终止本产品服务条款,删除您所有的 CDN 设置和数据,并不可恢复。
## 恢复
账户余额为正后,所有因欠费停止的项目均会自动重新启用。
因欠费导致清理的数据不可恢复。
# 计费概述
Source: https://bitiful-docs.mintlify.app/prices/basic
介绍对象存储。
## 计费周期
S4 以 **小时** 为周期,统计所有计费项的使用量,并按照使用量结算生成账单并扣费。
## 计费方式
S4 目前只支持 **阶梯按量/资源包** 计费,该计费方式为一种后付费方式,即先使用再付费。系统会自动按使用量乘以每小时单价计算费用,然后自动生成账单并扣费。更多信息,请参见下方的 `费用组成`。
## 费用组成
S4 服务费用由 [存储容量费用](/prices/detail/storage-prices)、[流量费用](/prices/detail/transfer-prices)、[请求费用](/prices/detail/requests-prices)、[数据处理费用](/prices/detail/processing-prices)和[自动证书费用](/prices/detail/autocerts-prices) 组成。
使用我们的价格计算器对比多家云成本:[https://tools.bitiful.com/prices/index.html](https://tools.bitiful.com/prices/index.html)
## 免费额度
前置条件 - [实名账户](https://console.bitiful.com/users):
* 前 50 GiB 存储
* 每月前 3\*10 GB HTTP/**HTTPS 流量**(每日每项限 5 GB)
* S4 出口流量 10GB/月
* 内置 CDN 回源 S4 流量 10GB/月
* 内置 CDN 出口流量 10GB/月
* 每月前 3\*10 万次 请求(每日每项限 1 万次)
* S4 请求数 10万次/月
* 内置 CDN 回源 S4 请求数 10万次/月
* 内置 CDN 请求数 10万次/月
* 前 5 个 Let's Encrypt 单域名 **自动证书**
# 自动证书费用
Source: https://bitiful-docs.mintlify.app/prices/detail/autocerts-prices
自动证书申请、更新域名证书。
缤纷云自动证书 PRO 正式发布,限时 5 折至 2027 年 1 月 1 日。
缤纷云自动证书可 **全自动管理** 在缤纷云部署的证书,关联的所有 CDN 均可自动更新。 还能通过 API 获取当前最新证书(PEM)实现 **其他平台的证书管理自动化**。
| 容量(GB) | 单价 |
| -------------- | ----------------------- |
| `前 5 个 LE 单域名` | 免费。 |
| `后续 LE 单域名` | 5元/个/次申请 ~~10元/个/次申请~~ |
| `所有 LE 泛域名` | 10元/个/次申请 ~~20元/个/次申请~~ |
| `所有 GTS 单域名` | 15元/个/次申请 ~~30元/个/次申请~~ |
| `所有 GTS 泛域名` | 30元/个/次申请 ~~60元/个/次申请~~ |
**约束与细节**
1. 同一个证书内最多包含 10 个域名(若为泛域名,自动包含主域,不算个数);
2. 多个域名的证书 **不要求**全部为同一主域,也不额外计费(仅按上面列表中的域名种类与个数计费);
3. 新申请和每次更新域名,都会自动扣费,请保证账户内余额充足
# 媒体处理费用
Source: https://bitiful-docs.mintlify.app/prices/detail/processing-prices
对象存储和CDN存储请求费用细则。
## 基础处理 - 完全免费
* 原图 20MB 以内
* 输入图为 PNG/JPEG/GIF/HEIC/AVIF 且输出为 JPEG/PNG 等常规格式 8bit 色深
* 输出类型:静态 SDR 图
## 高级处理 - 测试阶段免费
*`高色深支持就绪`*、*`完整 HDR 处理管线就绪`*
* Raw 格式输入
* PNG、JXL、AVIF、HEIC 等高级格式输出
* 10bit+ 输出
* HDR 图片输出
* GIF/APNG/WEBP/AVIF 动图输出
* 大于 20MB 原图输入
## 截帧处理 - 测试阶段免费
*`高色深支持就绪`*、*`完整 HDR 处理管线就绪`*
* 视频截帧
* GIF 截帧(*高质量处理*)
## 视频处理 - 测试阶段免费
*`高色深支持就绪`*、*`完整 HDR 处理管线就绪`*
* 视频压缩
* 视频 转 GIF
* GIF 转 视频
* 实时 M3U8
## 实况照片处理 - 测试阶段免费
*`高色深支持就绪`*、*`完整 HDR 处理管线就绪`*
* 实况照片静图提取/处理(完整 HDR 处理管线就绪)
* 实况照片视频提取/处理(完整 HDR 处理管线就绪)
* 实况照片互转与合成处理(支持 `oppo/huawei/xiaomi/vivo 方案的 motion photo` 和 `Apple live photo`)
**注意** 当前处于测试阶段,暂不收费。收费时间及标准会另行通知,请您及时关注相应公告。
CoreIX 媒体处理使用说明。
# 请求费用
Source: https://bitiful-docs.mintlify.app/prices/detail/requests-prices
对象存储和CDN存储请求费用细则。
您可以通过 S4控制台、S3 SDK、S3 API、客户端工具 等多种方式使用 S4 对象存储,但不管使用哪一种方式,操作都是通过调用 S4 API 来实现的,会产生请求次数费用。
## S4 请求费
| 请求(万次) | 单价 |
| -------- | -------- |
| `0 ~ 10` | **免费** |
| `11+` | 0.02元/万次 |
## S4 回源请求费(从内置 CDN)
| 请求(万次) | 单价 |
| -------- | -------- |
| `0 ~ 10` | **免费** |
| `11+` | 0.02元/万次 |
## CDN 全球请求费(6 月 22 日开始计费)
| 请求(万次) | 单价 | 闲时价格(00\~08 点) |
| -------- | ---------- | -------------- |
| `0 ~ 10` | **免费** | - |
| `11+` | 0.035 元/万次 | 0.02 元/万次 |
CDN 请求包低至 **暂不调整 低至 9.9元/亿次**: [https://console.bitiful.com/billing/resource](https://console.bitiful.com/billing/resource)
**计费细节**
1. `S4 请求费` 和 `S4 回源请求费` 免费额度为各自独立的 10万次/月;
2. 计费最小单位为 千次/账户,即:当前账户 3个桶,当月的请求次数为 4.5 + 3.5 + 2.55 = 10.55万次 共则系统会按 0.6 万次 计费(前 10万次 免费);
3. 免费额度为每月10万次,但为防止滥用,目前限制每天免费用量最多为1万次(每天超过1万次会开始计费);
4. 免费额度和资源包抵扣请求次数时没有“最低计费单位”的问题。
# 存储费用
Source: https://bitiful-docs.mintlify.app/prices/detail/storage-prices
对象存储存储容量费用细则。
与大多数主流对象存储采用固定费用不同,S4 采用阶梯计费,旨在尽可能降低您的存储成本。
| 容量(GB) | 单价 |
| ---------------- | ----------- |
| `0 ~ 50` | 免费。 |
| `51 ~ 1000 ` | 0.065元/GB/月 |
| `1001 ~ 10000` | 0.055元/GB/月 |
| `10001 ~ 100000` | 0.045元/GB/月 |
| `100000 + ` | 0.04元/GB/月 |
**计费细节**
1. 单位为 TB、GB、MB、KB、Bytes,即:1 TB = 1000 GB = 1000000 MB 以此类推;
2. 计费最小单位为 1GB/账户,即:当前账户 A、B、C 三个桶,容量为 10.5 + 20.5 + 30.5 = 61.5GB 共则系统会按 12GB 计费(前 50GB 免费);
3. 每个小时 S4 产生的出口流量数可抵扣当前小时相应容量的存储费用,即:该小时 A、B、C 三个桶的出口流量总共为 40GB,则该小时存储费用全免(12GB存储费用被40GB流量抵消)
4. **没有** 64KB的单个文件最小计费限制;
5. **没有** 90天 的最低计费时间;
# 流量费用
Source: https://bitiful-docs.mintlify.app/prices/detail/transfer-prices
对象存储和CDN存储出口流量费用细则。
限时**限量**充值赠额券:**BTF2026**
1. *充值 200 元起使用该券额外送 30% 余额,使用赠额券的充值 **不能退款***
2. *同账户可用多次,共 500 次,用完为止*
## S4 直接出口流量( 6 月 22 日上调,资源包价格暂时不变)
| 流量(GB) | 单价 | 闲时折扣(00\~08 点) |
| ---------------- | --------- | -------------- |
| `0 ~ 10` | **免费** | - |
| `11 ~ 1000 ` | 0.26 元/GB | 8折 |
| `1001 ~ 10000` | 0.22 元/GB | 8折 |
| `10001 ~ 100000` | 0.2 元/GB | 8折 |
| `100000 + ` | 0.18 元/GB | 8折 |
新价格S4 流量包低至 **0.072元/GB**: [https://console.bitiful.com/billing/resource](https://console.bitiful.com/billing/resource)
## S4 回源流量单价(6 月 22 日下调):
| 流量(GB) | 单价 | 变动 |
| ---------------- | ---------- | ------- |
| `0 ~ 10` | **免费** | - |
| `11 ~ 1000 ` | 0.1 元/GB | ↓ 16.7% |
| `1001 ~ 10000` | 0.085 元/GB | ↓ 15% |
| `10001 ~ 100000` | 0.07 元/GB | ↓ 20% |
| `100000 + ` | 0.055 元/GB | ↓ 37.5% |
## CDN 大陆节点出口流量
| 流量(GB) | 单价 |
| ---------------- | -------- |
| `0 ~ 10` | **免费** |
| `11 ~ 1000 ` | 0.12元/GB |
| `1001 ~ 10000` | 0.10元/GB |
| `10001 ~ 100000` | 0.09元/GB |
| `100000 + ` | 0.08元/GB |
## CDN 海外节点出口流量(6 月 22 日期单独计费)
| 流量(GB) | 单价 |
| ---------------- | --------- |
| `0 ~ 1000 ` | 0.46 元/GB |
| `1001 ~ 10000` | 0.38 元/GB |
| `10001 ~ 100000` | 0.30 元/GB |
| `100000 + ` | 0.24 元/GB |
**计费细节**
1. `S4 出口流量`、`内置 CDN 回源流量`和`CDN 出口流量` 三者免费额度各自独立;
2. 单位为 TB、GB、MB、KB、Bytes,即:1 TB = 1000 GB = 1000000 MB 以此类推;
3. 计费最小单位为 1MB/小时/账户,即:某个小时流量消耗 101.4 MB,计费时会取整为 102 MB;
4. 免费额度为每月每项10GB,但为防止滥用,目前限制每天用量不能超过5GB(当天超过5GB后会开始计费);
5. 资源包、免费额度再帮在抵扣时,没有“最小计费单位”问题。