快速入门
1. 前置准备
1.1 获取 AK/SK
登录 七牛云控制台 → 个人中心 → 密钥管理,获取 AccessKey 和 SecretKey。
1.2 两组接入点
| 用途 | 接入域名 | 鉴权方式 | 适用接口 |
|---|---|---|---|
| 域名管理 & 配置 | api.qiniu.com |
Qiniu 鉴权 | 域名管理、域名配置 |
| 其他所有接口 | fusion.qiniuapi.com |
QBox 鉴权 | 统计/缓存/证书/日志 |
不可混用。域名管理发到 fusion 会 404,统计接口发到 api 也会 404。
鉴权算法详见 鉴权指南。
1.3 安装 Python SDK (生成签名)
pip install qiniu requests
1.4 签名生成工具函数
后续所有示例共用此函数:
from qiniu import Auth, QiniuMacAuth
from urllib.parse import urlencode
import requests, json
AK = "<你的AccessKey>"
SK = "<你的SecretKey>"
def call_api(method, path, body=None):
"""api.qiniu.com 接口 (Qiniu 鉴权)"""
url = f"https://api.qiniu.com{path}"
auth = QiniuMacAuth(AK, SK)
headers = {"Content-Type": "application/json"}
raw = json.dumps(body, separators=(',', ':')) if body else None
token = auth.token_of_request(
method, "api.qiniu.com", url,
qheaders=None, content_type="application/json", body=raw
)
headers["Authorization"] = f"Qiniu {token}"
resp = requests.request(method, url, headers=headers, data=raw)
return resp.status_code, resp.json() if resp.text else {}
def call_fusion(method, path, body=None, params=None):
"""fusion.qiniuapi.com 接口 (QBox 鉴权)"""
# QBox 签名必须包含完整 URL (query string 参与签名)
base = f"https://fusion.qiniuapi.com{path}"
if params:
base = f"{base}?{urlencode(params)}"
auth = Auth(AK, SK)
token = auth.token_of_request(base)
headers = {"Content-Type": "application/json", "Authorization": f"QBox {token}"}
resp = requests.request(method, base, headers=headers, json=body)
return resp.status_code, resp.json() if resp.text else {}
2. 典型流程
步骤 1:创建域名
code, body = call_api("POST", "/domain/cdn.example.com", {
"type": "normal",
"platform": "web",
"geoCover": "foreign",
"protocol": "http",
"source": {"sourceType": "ip", "sourceIPs": ["1.2.3.4"], "testURLPath": "/index.html"},
"cache": {"cacheControls": [{"time": 1, "timeunit": 5, "type": "all", "rule": "*"}]},
"testURLPath": "/index.html"
})
print(code, body)
# 成功: 200 {}
# 重复: 400 {"code":400062,"error":"重复域名"}
创建后状态为 processing,5-10 分钟变为 success 才能操作。
步骤 2:查询域名状态
code, body = call_api("GET", "/domain/cdn.example.com")
print(body.get("operatingState")) # processing → success
print(body.get("cname")) # 用于 DNS 解析的 CNAME 值
拿到 CNAME 后去 DNS 服务商添加 CNAME 记录指向该值。
步骤 3:配置缓存规则
code, body = call_api("PUT", "/domain/cdn.example.com/cache", {
"cacheControls": [
{"time": 30, "timeunit": 0, "type": "suffix", "rule": ".jpg;.png;.css;.js"},
{"time": 1, "timeunit": 2, "type": "all", "rule": "*"}
],
"ignoreParam": False
})
# timeunit: 0=秒 1=分 2=小时 3=天
# type=all + rule=* 为全局兜底规则 (必须有)
步骤 4:上传证书 & 开启 HTTPS
# 4a. 上传证书
code, body = call_fusion("POST", "/sslcert", {
"name": "cdn.example.com-2026",
"commonName": "cdn.example.com",
"pri": open("private.key").read(),
"ca": open("fullchain.pem").read()
})
cert_id = body.get("certID")
print(f"证书ID: {cert_id}")
# 4b. 开启 HTTPS
code, body = call_api("PUT", f"/domain/cdn.example.com/sslize", {
"ssl": {"certId": cert_id, "forceHttps": True, "http2Enable": True}
})
步骤 5:刷新缓存
code, body = call_fusion("POST", "/v2/tune/refresh", {
"urls": [
"https://cdn.example.com/index.html",
"https://cdn.example.com/style.css"
]
})
request_id = body.get("requestId")
print(f"剩余配额: {body.get('urlSurplusDay')}")
# 查询刷新状态
code, body = call_fusion("POST", "/v2/tune/refresh/list", {
"requestId": request_id
})
for item in body.get("items", []):
print(f"{item['url']} → {item['state']}")
步骤 6:查询带宽/流量
code, body = call_fusion("POST", "/v2/tune/bandwidth", {
"domains": "cdn.example.com", # string, 分号分隔
"startDate": "2026-02-01",
"endDate": "2026-02-13",
"granularity": "day" # 5min / hour / day
})
print(body.get("data"))
步骤 7:查询命中率/状态码
code, body = call_fusion("POST", "/v2/tune/loganalyze/hitmiss", {
"domains": ["cdn.example.com"], # array, 注意和05不同!
"startDate": "2026-02-01",
"endDate": "2026-02-13",
"freq": "1day" # 5min / 1hour / 1day (带数字前缀)
})
print(body.get("data"))
步骤 8:下载访问日志
code, body = call_fusion("POST", "/v2/tune/log/list", {
"day": "2026-02-12", # 仅单日
"domains": "cdn.example.com" # string, 分号分隔
})
for domain, logs in body.get("data", {}).items():
for log in logs:
print(f"{log['name']} {log['size']}B {log['url'][:80]}...")
3. 关键避坑
3.1 参数类型差异 (最常踩坑)
| 场景 | domains 类型 | 时间粒度 | 时间跨度 |
|---|---|---|---|
| 用量统计 | string "a.com;b.com" |
granularity: 5min/hour/day |
≤ 31 天 |
| 运营统计 | array ["a.com","b.com"] |
freq: 5min/1hour/1day |
≤ 30 天 |
| 日志下载 | string "a.com;b.com" |
仅单日 day | - |
3.2 域名配置 Body 不包层
# ✅ 正确: 直传字段
call_api("PUT", "/domain/xxx/source", {"sourceType": "domain", ...})
call_api("PUT", "/domain/xxx/cache", {"cacheControls": [...], "ignoreParam": True})
call_api("PUT", "/domain/xxx/range", {"enable": "off"})
# ❌ 错误: 多包一层
call_api("PUT", "/domain/xxx/source", {"source": {"sourceType": ...}}) # 400
call_api("PUT", "/domain/xxx/cache", {"cache": {"cacheControls": ...}}) # 400309
3.3 高频错误速查
| 错误码 | 含义 | 解法 |
|---|---|---|
| 400062 | 重复域名 | 已存在,无需创建 |
| 400030 | 正在处理中 | 等 5-10 分钟 |
| 400317 | 非已下线域名 | 删除前须先下线 |
| 400309 | 缓存未设全局 | cacheControls 须含 type=all 兜底 |
| 400331 | 非法参数 | freq 用 1day 非 day,跨度 ≤ 30 天 |
| 400034 | 刷新配额超限 | 每日 500 次,次日恢复 |
| 400033 | 预取配额超限 | 每日 100 次,次日恢复 |
| 401001 | 签名不匹配 | 检查 AK/SK、签名算法、域名对应关系 |
| 403024 | QPS 超限 | api 10 QPS / fusion 5-10 QPS |
4. curl 速查
4.1 Qiniu 鉴权
curl -X GET 'https://api.qiniu.com/domain' \
-H 'Host: api.qiniu.com' \
-H 'Content-Type: application/json' \
-H 'Authorization: Qiniu <AK>:<Sign>'
4.2 QBox 鉴权
curl -X POST 'https://fusion.qiniuapi.com/v2/tune/bandwidth' \
-H 'Host: fusion.qiniuapi.com' \
-H 'Content-Type: application/json' \
-H 'Authorization: QBox <AK>:<Sign>' \
-d '{"domains":"cdn.example.com","startDate":"2026-02-01","endDate":"2026-02-13","granularity":"day"}'
文档反馈
(如有产品使用问题,请 提交工单)