参考链接:

搭建博客过程中,不可避免的就是搭建一个属于自己的图床,本着能白嫖就绝不付费的精神,我尝试使用GitHub搭建图床并使用cloudflare进行加速访问,并将搭建过程记录下来。

github操作

创建github仓库

首先创建一个github仓库用于存储图片,注意需要设置为public
创建仓库

创建Token

为了访问我们的仓库,需要创建Token,直接点击链接https://github.com/settings/tokens 即可设置,这里选择classic
设置Token

注意:创建Token时,一定要勾上repo选项,其他权限随意,过期时间可以自己把握,创建完成后,Token只会展示一次,请妥善保管
repo

下载并配置PicGo

PicGo是一个开源的图床管理客户端,支持七牛图床、腾讯云 COS、又拍云 、GitHub、SM.MS、阿里云 OSS、Imgur v1.6.0
下载链接: https://github.com/Molunerfinn/picgo/releases
因为我们使用github搭建图床,所以这里给出github的配置
配置如下:

  • 图床配置名:自己定义
  • 设定仓库名:github用户名/仓库名,如:githubaccount/myblogpic
  • 设定分支名:仓库分支,在网页添加README文件即可创建main分支
  • 设定Token:刚刚获取的Token
  • 设定存储路径:选填,顾名思义
  • 设置自定义域名:后续cloudflare讲解
    github图床配置

建议安装super-prefix插件,可以给上传的图片自动命名,方便整理,如果遇到下载不成功问题可以配置npm的淘宝镜像源解决,这里不再赘述。

到此为止便搭建完成图库了,不需要进行加速的就不用往下看了,后续内容是使用cloudflare加速图床访问的记录。

cloudflare加速访问

cloudflare真是个大善人,白嫖了不少东西。
搭建完成图库后发现网页访问变慢了,其原因就是github的访问问题,虽然开图片懒加载会解决一部分问题,但是归根到底不是长久之计

于是便想到使用cloudflare的workers功能进行加速。cloudflare每日给了100,000次免费请求数,对于个人用户肯定是够用了。
必要条件:

  • 有一个自己的域名
  • 域名托管到cloudflare

这部分网络上有很多教程,不再赘述。

创建workers

打开cloudflare官网,进入workers and pages页面,点击创建
workersandpages
名字随便起,这里会给你分配一个免费的三级域名,但是不建议使用这个域名,有概率无法访问。设置完成后点击部署
设置worker
点击编辑代码
编辑代码
修改worker.js内容,参考来源:https://james-blog.top/posts/21.html
代码如下,直接粘贴就好,报错也不用管。
注意:修改代理路径和token内容,其他内容无需修改。

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Website you intended to retrieve for users.
const upstream = "raw.githubusercontent.com";

// Custom pathname for the upstream website.
// (1) 填写代理的路径,格式为 /<用户>/<仓库名>/<分支>
const upstream_path = "****";

// github personal access token.
// (2) 填写github令牌
const github_token = "****";

// Website you intended to retrieve for users using mobile devices.
const upstream_mobile = upstream;

// Countries and regions where you wish to suspend your service.
const blocked_region = [];

// IP addresses which you wish to block from using your service.
const blocked_ip_address = ["0.0.0.0", "127.0.0.1"];

// Whether to use HTTPS protocol for upstream address.
const https = true;

// Whether to disable cache.
const disable_cache = false;

// Replace texts.
const replace_dict = {
$upstream: "$custom_domain",
};

addEventListener("fetch", (event) => {
event.respondWith(fetchAndApply(event.request));
});

async function fetchAndApply(request) {
const region = request.headers.get("cf-ipcountry")?.toUpperCase();
const ip_address = request.headers.get("cf-connecting-ip");
const user_agent = request.headers.get("user-agent");

let response = null;
let url = new URL(request.url);
let url_hostname = url.hostname;

if (https == true) {
url.protocol = "https:";
} else {
url.protocol = "http:";
}

if (await device_status(user_agent)) {
var upstream_domain = upstream;
} else {
var upstream_domain = upstream_mobile;
}

url.host = upstream_domain;
if (url.pathname == "/") {
url.pathname = upstream_path;
} else {
url.pathname = upstream_path + url.pathname;
}

if (blocked_region.includes(region)) {
response = new Response(
"Access denied: WorkersProxy is not available in your region yet.",
{
status: 403,
}
);
} else if (blocked_ip_address.includes(ip_address)) {
response = new Response(
"Access denied: Your IP address is blocked by WorkersProxy.",
{
status: 403,
}
);
} else {
let method = request.method;
let request_headers = request.headers;
let new_request_headers = new Headers(request_headers);

new_request_headers.set("Host", upstream_domain);
new_request_headers.set("Referer", url.protocol + "//" + url_hostname);
new_request_headers.set("Authorization", "token " + github_token);

let original_response = await fetch(url.href, {
method: method,
headers: new_request_headers,
body: request.body,
});

let connection_upgrade = new_request_headers.get("Upgrade");
if (connection_upgrade && connection_upgrade.toLowerCase() == "websocket") {
return original_response;
}

let original_response_clone = original_response.clone();
let original_text = null;
let response_headers = original_response.headers;
let new_response_headers = new Headers(response_headers);
let status = original_response.status;

if (disable_cache) {
new_response_headers.set("Cache-Control", "no-store");
} else {
new_response_headers.set("Cache-Control", "max-age=43200000");
}

new_response_headers.set("access-control-allow-origin", "*");
new_response_headers.set("access-control-allow-credentials", "true");
new_response_headers.delete("content-security-policy");
new_response_headers.delete("content-security-policy-report-only");
new_response_headers.delete("clear-site-data");

if (new_response_headers.get("x-pjax-url")) {
new_response_headers.set(
"x-pjax-url",
response_headers
.get("x-pjax-url")
.replace("//" + upstream_domain, "//" + url_hostname)
);
}

const content_type = new_response_headers.get("content-type");
if (
content_type != null &&
content_type.includes("text/html") &&
content_type.includes("UTF-8")
) {
original_text = await replace_response_text(
original_response_clone,
upstream_domain,
url_hostname
);
} else {
original_text = original_response_clone.body;
}

response = new Response(original_text, {
status,
headers: new_response_headers,
});
}
return response;
}

async function replace_response_text(response, upstream_domain, host_name) {
let text = await response.text();

var i, j;
for (i in replace_dict) {
j = replace_dict[i];
if (i == "$upstream") {
i = upstream_domain;
} else if (i == "$custom_domain") {
i = host_name;
}

if (j == "$upstream") {
j = upstream_domain;
} else if (j == "$custom_domain") {
j = host_name;
}

let re = new RegExp(i, "g");
text = text.replace(re, j);
}
return text;
}

async function device_status(user_agent_info) {
var agents = [
"Android",
"iPhone",
"SymbianOS",
"Windows Phone",
"iPad",
"iPod",
];
var flag = true;
for (var v = 0; v < agents.length; v++) {
if (user_agent_info.indexOf(agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
}

修改完成后点击部署
部署

绑定域名

请确认已经将你自己的域名托管到cloudflare,这部分不再赘述。
依次点击设置添加自定义域
绑定域名

起一个二级域名,如:imags.xxxx.com
二级域名

设置完成后即可使用自己的域名进行图床图片访问。

PicGo设置

最后一步,在刚刚PicGo的配置中设定自定义域名,注意末尾不要加/,不然访问会有问题
自定义域名