Backblaze B2 + Cloudflare:10GB 的图片或文件存储方案

前言

大部分的存储桶可能都有免费计划,但几乎后面都会收费,尤其是流量费用。Backblaze 有些不同,免费 10GB 存储,每天 1GB 下行流量,超过就会开始计费。
但是,Backblaze 在 Bandwidth Alliance 下使得数据传输(带宽)费用为0。

Backblaze and Cloudflare Partner to Provide Free Data Transfer

开始

开始前可参考官方的教程
Using Backblaze B2 with the Cloudflare CDN

注册 Backblaze

https://www.backblaze.com/b2/sign-up.html
如果点击注册没有反应,则可能需要代理。

创建 Bucket

新建一个桶,如果 public(公众,机翻急死我了)无法点击则需要点击 verify now 验证邮箱。
完成检查邮箱完成认证即可返回之前的页面创建。
按需选择创建即可。
创建桶

获取公共 URL

点击 Upload/Download
随便上传一个测试文件,然后点击测试文件,将
Friendly URL 域名复制下来。
公共 URL

Cloudflare 解析

新建一条 CNAME 解析,并解析到之前获取的 URL.
公共 URL

测试 可访问性

打开之前上传的文件,替换成刚刚你绑定的域名。
可访问到这说明已经大功告成!
Test

美化 URL 和隐藏 Bucket 名称

这一步需要使用Cloudflare workers
worker 的代码使用的是 使用 Backblaze B2 和 Cloudflare Workers 搭建免费的自定义域名图床 | 驱蚊器喵的插座 的 worker 代码。
使用这个的话每天有10万次请求限制(免费计划),但是它可以保护我们的 b2 Bucket URL 防止被刷流量。

但这个大佬的方法用的不是 worker可参考:
https://blog.winer.website/archives/use_blackblaze_b2_and_cloudflare_cdn_to_bulid_a_free_oss.html

新建一个 worker,启动器选择 HTTP路由器。
点击编辑,将左边全部删除,将以下代码复制到左边(手机长按,然后点击 Paste)


  • b2Domain:你所绑定的域名
  • b2Bucket:存储桶名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
'use strict';
const b2Domain = 'img.domain.com'; // configure this as per instructions above
const b2Bucket = 'bucket-name'; // configure this as per instructions above
const b2UrlPath = `/file/${b2Bucket}/`;
addEventListener('fetch', event => {
return event.respondWith(fileReq(event));
});

// define the file extensions we wish to add basic access control headers to
const corsFileTypes = ['png', 'jpg', 'gif', 'jpeg', 'webp'];

// backblaze returns some additional headers that are useful for debugging, but unnecessary in production. We can remove these to save some size
const removeHeaders = [
'x-bz-content-sha1',
'x-bz-file-id',
'x-bz-file-name',
'x-bz-info-src_last_modified_millis',
'X-Bz-Upload-Timestamp',
'Expires'
];
const expiration = 31536000; // override browser cache for images - 1 year

// define a function we can re-use to fix headers
const fixHeaders = function(url, status, headers){
let newHdrs = new Headers(headers);
// add basic cors headers for images
if(corsFileTypes.includes(url.pathname.split('.').pop())){
newHdrs.set('Access-Control-Allow-Origin', '*');
}
// override browser cache for files when 200
if(status === 200){
newHdrs.set('Cache-Control', "public, max-age=" + expiration);
}else{
// only cache other things for 5 minutes
newHdrs.set('Cache-Control', 'public, max-age=300');
}
// set ETag for efficient caching where possible
const ETag = newHdrs.get('x-bz-content-sha1') || newHdrs.get('x-bz-info-src_last_modified_millis') || newHdrs.get('x-bz-file-id');
if(ETag){
newHdrs.set('ETag', ETag);
}
// remove unnecessary headers
removeHeaders.forEach(header => {
newHdrs.delete(header);
});
return newHdrs;
};
async function fileReq(event){
const cache = caches.default; // Cloudflare edge caching
const url = new URL(event.request.url);
if(url.host === b2Domain && !url.pathname.startsWith(b2UrlPath)){
url.pathname = b2UrlPath + url.pathname;
}
let response = await cache.match(url); // try to find match for this request in the edge cache
if(response){
// use cache found on Cloudflare edge. Set X-Worker-Cache header for helpful debug
let newHdrs = fixHeaders(url, response.status, response.headers);
newHdrs.set('X-Worker-Cache', "true");
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHdrs
});
}
// no cache, fetch image, apply Cloudflare lossless compression
response = await fetch(url, {cf: {polish: "lossless"}});
let newHdrs = fixHeaders(url, response.status, response.headers);

if(response.status === 200){

response = new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHdrs
});
}else{
response = new Response('File not found!', { status: 404 })
}

event.waitUntil(cache.put(url, response.clone()));
return response;
}

worker 弄好以后,进入你的 域名菜单 - Workers
来添加路由。
路由填上你绑定的域名并在后面加/*
选择好 worker 点击保存。
路由

完成

现在你就可以通过 example.com/filename.mp3 访问你的文件。
由于使用 Cloudflare workers,每天有10万次访问限制。

Demo

PID=100888311_15周年おめでとうございます!_UID=40745221_p0.jpg
https://b2.xiaolan.eu.org/PID=100888311_15周年おめでとうございます!_UID=40745221_p0.jpg


Backblaze B2 + Cloudflare:10GB 的图片或文件存储方案
https://blog.ltya.top/posts/BackblazeB2+Cloudflare.shtml
作者
岚天呀
发布于
2022-9-9
更新于
2022-9-23
许可协议