Backblaze云存储价格低廉,还免费赠送10G存储空间,并且还加入了Bandwidth Alliance(带宽联盟),因此从Backblaze B2到CloudFlare的流量大部分是免费的,因此我们可以使用CloudFlare缓存B2中的内容,直接走CloudFlare以此规避流量费用。

1.注册backblaze平台账号,并创建一个存储桶

2.点击桶设置,设置缓存时长


输入

{"cache-control":"max-age=720000"}

3.进入刚创建的存储桶中,上传一张图片,然后点击图片,将其中域名记录下来

4.打开cloudflare平台,添加一条CNAME记录,指向刚获得的图片地址域名

5.将SSL加密模式设置为完全


设置好解析后,可以使用:你的解析域名/file/存储桶名称/文件名 访问查看是否解析成功

6.添加规则

7.添加一条缓存规则,URL为:https://域名/file/存储桶名称/*

8.添加一条302转发规则,如果通过该域名访问其它桶的文件,则跳到404页面

URL为:https://域名/file// 转发到:https://secure.backblaze.com/404notfound

9.使用cf的Workers以隐藏存储桶名称,选择管理 Workers ,然后创建服务,编辑并添加脚本代码


将下面代码粘贴进去并修改代码开头的两个变量即可

'use strict';
const b2Domain = '解析的域名'; // configure this as per instructions above
const b2Bucket = '存储桶名称'; // 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);
  response = new Response(response.body, {
    status: response.status,
    statusText: response.statusText,
    headers: newHdrs
  });

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

添加好代码后,将解析的域名添加进路由中即可

设置好后可以直接通过:你的解析域名/文件名 访问,可以不用使用:域名/file/存储桶名称/文件名 也能访问文件,以此达成隐藏存储桶名称。

10.在浏览器控制台中查看图片是否命中缓存

11.其它

CF的Workers免费套餐中每24小时的请求限制为10万个,如果超量会收费的,参考https://developers.cloudflare.com/workers/platform/pricing

另外还有B2存储中的B类和C类交易的免费请求上限是2500个,超量会收费

如果只是分享给自己朋友,那么可能会没事