前言
相信绝大多数Blogger都有使用对象存储的需求,国内诸如阿里云、腾讯云、七牛云、华为云等多个厂家也都提供了自家的图床。
博主之前也曾使用过七牛云的存储服务,虽然使用七牛云一年以来,所支付的费用也不算多,但收费规则对我来说还是模糊的,继续使用下去的意愿也不大了其实是懒得算账
那么有没有完全免费的图床可以用呢?之前也使用过jsDelivr+Github的组合拳,但jsDelivr一直被干扰,实际上在大陆体验效果一般,况且用作图床Github仓库也必须是公开的,也不便于管理。
Backblaze为什么是神?
在把整个博客部署到Cloudflare Pages之后,机缘之下,我发现了BackBlaze提供的存储服务,其B2云存储提供10GB的免费空间,10GB对我来说是很奢侈了,而且每天也有1GB的免费下载流量,个人博客而言完全够用。
即使你使用的存储额度超出了10GB,超过的部分每月也只按0.005USD/GB的价格收费,下载量超过1GB也仅仅只需0.01USD/GB。
0.005USD≈0.036RMB
那么为什么我要提到Cloudflare呢?那是因为Backblaze与Cloudflare一样是带宽联盟(Bandwidth Alliance)的合作伙伴,使用Cloudflare提供的CDN服务访问Backblaze的资源是不存在数据传输费用的。如此,你就能够拥有一个近乎免费的云存储空间。
Backblaze的优点:
- 便宜量大管饱
- API丰富,有成熟的讨论社区
- 资源上传方式多样
- 不限制存储文件类型,你甚至可以用它当云盘(我没这么干过)
Backblaze的缺点:
- 云存储服务架设在国外,国内访问存在风险
- 学习成本略高,官网中文翻译一坨
Cloudflare又是什么高手了?
Cloudflare 的主要产品和服务包括内容传递网络(CDN)、DDoS 攻击防护、DNS(域名系统)服务、防火墙、安全服务和分布式存储等。该公司通过其全球分布的数据中心网络,将用户的网站流量路由到离用户最近的服务器,从而加速网站加载速度,提高性能,并保护网站免受各种网络攻击的侵害。
Cloudflare Pages提供免费的静态博客部署服务(如你所见,我的博客就是通过这个服务搭建而来),Cloudflare Workers提供类似Github Actions的免费无服务器应用程序。
All you need:
- Backblaze账号
- Cloudflare账号
- 你自己的域名
- 耐心
Backblaze创建存储桶
进入官网,点击Get Started
,选择B2 Cloud Storage
中的Try for Free
,登录账号,点击Create a Bucket
创建存储桶,你会看到如下界面:
注意,此处的Bucket
应设置为Private
,因为不知从什么时候起,创建Public
的桶就需要在Backblaze上绑定信用卡并有消费记录或是一次性支付1USD作为创建这个桶所需要的价格,那显然是不符合能省钱就省钱的价值观的。并且Public的桶存在被人恶意刷流量的可能,所以理论上还是Private
的桶更保险一些,至于Default Encryption
与Object Lock
保持默认即可。
Bucket Unique Name
随意,建议设置得复杂一些。
PS:建议关闭不知所云的中文翻译
选做:打开创建的存储桶的Bucket Settings,在Bucket Info中添加{“cache-control”:”max-age=43200”}
之后我们点击Upload/Download
图标上传一张图片,在Browse Files
里点开存有图片的桶,随机点开一张,查看详细信息,我们需要使用到的访问图片的链接是Friendly URL
。
Friendly URL
有其固定的结构,假设一张图片的Friendly URL
是f002.backblazeb2.com/file/any-bucket-name/avatar.png
,那么这张图片的URL可分为:
- 主机名(记住这个):
f002.backblazeb2.com
- 文件后缀:
file
- 存储桶名称:
any-bucket-name
- 图片的路径:
avatar.png
到这里,我们的工作转向Cloudflare
使用Cloudflare托管你的域名
为了能够将你的域名托管到Cloudflare上,你需要将你自己的域名的NS修改为Cloudflare提供的NS,同时将所有DNS解析都转移到Cloudflare上,网上有许多优秀详细的教程,请根据你自己的域名提供商寻找相应的解决方法。
之后,在Cloudflare里添加一条CNAME
记录,Name
填上你的二级域名,Target
填上Friendly URL
中的主机名。
这样就相当于,你用自己托管的域名(假设为yourdomain.site
)设置了一个二级域名file.yourdomain.site
,将其指向B2主机名f002.backblazeb2.com
。
那么原本的图片URLf002.backblazeb2.com/file/any-bucket-name/avatar.png
就可以用file.yourdomain.site/file/any-bucket-name/avatar.png
访问,此时我们可以一试,会发现没有Token无法访问,报错信息如下:
1 | { |
不过更常见的状况应该是Error 522:Connection timed out
:
为什么呢?默认情况下的Cloudflare通过纯HTTP访问上游服务器,而Backblaze仅支持HTTPS连接,所以Cloudflare发出的HTTP请求失败。
为了解决这一问题,将Cloudflare仪表板中的SSL/TLS中的加密模式改为Full (strict):
接下来,我们来优化访问图片的URL
创建规则重写访问图片URL
单击Cloudflare仪表板左侧的Rules,然后点击进入Transform Rules,如果你使用Cloudflare的免费计划,那么你一共有10条免费的规则可以设置(对于此教程,我们只需要两条规则)
在Rewrite URL
下创建一条规则,首先看到When incoming requests match…
部分,设置如下图:
我们希望能够直接以二级域名+图片路径
的方式访问图片,而不是需要额外添加/file/<桶名称>
来访问,为了达成这一目的,我们需要在Then
中设置Path
,具体设置如下图:
这个表达式相当于当你在使用file.yourdomain.site/xxx.jpg
访问图片时,会自动拼接成file.yourdomain.site/file/<你的桶名>/xxx.jpg
,这一过程并不会显式地改变你访问的URL,相当于隐藏了你的桶名。
由于我们的桶是Private
的,我们需要一个Token来访问它,所以在Query
这里我们需要额外设置:
Authorization=
后的值可以瞎填,后面再处理。
修改http响应头
接下来我们需要优化响应头,提高性能,将Transform Rules
切换到Modify Response Header
,添加一条规则,If...
配置如下图:
Then
的设置比较多,如下表:
Header name | Value | |
---|---|---|
Set static | Access-Control-Allow-Origin | * |
Set dynamic | ETag | concat(http.response.headers[“x-bz-content-sha1”][0], http.response.headers[“x-bz-info-src_last_modified_millis”][0], http.response.headers[“x-bz-file-id”][0]) |
Set static | cache-control | public, max-age=31536000 |
Remove | x-bz-content-sha1 | |
Remove | x-bz-file-id | |
Remove | x-bz-file-name | |
Remove | x-bz-info-s3b-last-modified | |
Remove | x-bz-info-sha256 | |
Remove | x-bz-info-src_last_modified_millis | |
Remove | x-bz-upload-timestamp |
最后的结果:
使用Workers自动更新Token
我们回到Backblaze账户,申请一个Application Keys
,如下图:
Allow acces to Bucket(s)
选择你的桶名,勾选Read and Write
。
将生成的keyID
与applicationKey
保存好,回到Cloudflare。
创建一个Worker,在Edit Code
中填入如下代码:
1 | const config = { |
变量名 | 内容 |
---|---|
B2Key | keyID |
B2AppKey | applicationKey |
B2BucketName | 桶名 |
cfDomain | 你的访问域名 |
cfAuthEmail | Cloudflare账号邮箱 |
cfAuthKey | Cloudflare的Application Key |
cfZoneID | 你的域名的区域ID |
cfRulesetID | Cloudflare的规则集ID |
cfRuleID | Cloudflare的规则ID |
cfAuthKey
获取方法:点击右上人像,在My Profile
中的API Token
页,点击Global API Key
中的View
。
cfZoneID
获取方法:点击进入你托管的域名,在OverView
页面最右边栏中的API
处。
cfRulesetID
与cfRuleID
获取方法:
打开左边栏的Manage Account->Audit log
,找到Rulesets update
,点开之后按下图寻找:
如果没找着直接更新一下规则名称就出现了。
以上配置完成之后,你应该可以直接通过file.youdomain.site/xxx.jpg
访问到你想要的图片了。
你还可以设置Triggers
让Workers
每隔一段时间自动运行,我设置的是每4小时运行一次:
后记
至此你就拥有了一个免费的文件存储服务,而如何方便快捷地上传图片,请自行查找相关教程,此处不予介绍。