图片上传
Hive 帖子通过网址指向图片,所以应用需要一个上传图片的地方。imagehoster 是为 Hive 打造的开源图片托管程序。它可以接受那些用 Hivesigner 登录了您应用的人上传的图片:他们的访问令牌代替了用密钥所做的签名。
工作方式
- 用户用 Hivesigner 登录您的应用,并授予发布权限。您的应用收到一个访问令牌。参见使用 OAuth2 登录。
- 您的应用把图片发送到您的 imagehoster,并把该令牌放在网址中。
- imagehoster 检查令牌和账户,保存图片,并以图片的网址作答。
- 您的应用把网址放进帖子里。
自行运行 imagehoster
一个 imagehoster 只为一个应用账户配置:配置中 [upload_limits] 一节的 app_account。请只向它发送为该应用账户生成的令牌。公共实例属于别的应用:images.ecency.com 为 Ecency 的应用账户配置,images.hive.blog 为 Hive.blog 的应用账户配置。要接受您自己用户的上传,请用您的应用账户运行您自己的实例。
源码和部署指南:
- Hive 社区的 imagehoster:https://gitlab.syncad.com/hive/imagehoster
- Ecency 的 imagehoster:https://github.com/ecency/imagehoster
在配置中设置您的应用账户:
[upload_limits]
app_account = 'YOUR_APP_ACCOUNT'
同一节还设置账户上传所需的最低声誉(reputation),以及每个账户的上传配额(每 duration 毫秒 max 次上传)。请配置 redis_url,配额才会生效。max_image_size 设置最大文件大小,以字节计。
上传图片
POST /hs/ACCESS_TOKEN HTTP/1.1
Host: YOUR_IMAGEHOSTER
Content-Type: multipart/form-data; boundary=BOUNDARY
Content-Length: LENGTH
- 令牌。 把用户的访问令牌按 Hivesigner 交给您应用时的原样放进路径。请使用为您的应用、带发布权限登录所得到的令牌。来自不带
client_id请求的纯登录令牌没有写明任何应用,会被拒绝。 - 请求体。 发送
multipart/form-data,其中包含一个图片文件。无论字段名是什么,imagehoster 都取第一个文件。 - 大小。 请发送
Content-Length头。文件不得大于该实例的max_image_size。
回答是 JSON。成功时它包含图片的网址:
{ "url": "https://YOUR_IMAGEHOSTER/IMAGE_HASH/photo.jpg" }
失败时,imagehoster 以 HTTP 错误状态码作答。多数失败还会带上一个错误名称:
{ "error": { "name": "ERROR_NAME" } }
备注: 令牌在网址中传输。请只通过 https 提供您的 imagehoster,并妥善保管它的访问日志。
示例
下面这个浏览器函数会从文件输入框或拖放操作中上传一个文件。浏览器会替您设置 multipart 相关的请求头和长度:不要自行设置 Content-Type。
// IMAGEHOSTER_URL is the address of your imagehoster, such as 'https://YOUR_IMAGEHOSTER'.
async function uploadImage(file, accessToken) {
const body = new FormData();
body.append('file', file);
const response = await fetch(`${IMAGEHOSTER_URL}/hs/${accessToken}`, {
method: 'POST',
body,
});
const result = await response.json().catch(() => ({}));
if (!response.ok) {
throw new Error(result.error?.name ?? `Upload failed with status ${response.status}`);
}
return result.url;
}
const url = await uploadImage(input.files[0], ACCESS_TOKEN);
const markdown = ``; // add this to the post body