Skip to content

cdn 代理供应商

目前就是想用 jsdelivr 代理 github 图床,但是超限了。

text
cdn.jsdelivr.net Package size exceeded the configured limit of 50 MB.

50M 额度超限

针对仓库:

本仓库被当做是我的图床,为了高效率访问里面的文件,我用的是 cdn.jsdelivr.net 代理的方案。该方案现在遇到了 50M 超限的情况。 比如该图片:

目前查到一个方案是增加 branch 分支名,继续蹭 50M 的额度。

增加显性的分支名后,确实可以访问:

但是该方案确实给我带来焦虑,就是我不确定到底有多少图片的 url 需要增加分支名,维护起来不优雅,一旦再次超限,受影响的图片就很多。一大堆的文件都会受影响。

尝试寻找新的代理方案

该方案有效。

配置自己的 worker 代理脚本

上述的教程讲的是用 cloudflare 代理特定目标的地址。代理了 github。

我的核心需求是这样的:

必定可用的地址如下:

期望未来能用的地址如下:

地址 gh-img-store.ruan-cat.com 去代理 raw.githubusercontent.com/ruan-cat/img-store/main 地址。

根据此需求,改写教程提供的 worker 代码,最终生效的 worker 如下:

worker 代码
js
// 你要镜像的网站.
const 
upstream
= "raw.githubusercontent.com";
// 镜像网站的目录,比如你想镜像某个网站的二级目录则填写二级目录的目录名,镜像 google 用不到,默认即可. const
upstream_path
= "/ruan-cat/img-store/main/";
// 镜像站是否有手机访问专用网址,没有则填一样的. const
upstream_mobile
= "raw.githubusercontent.com";
// 屏蔽国家和地区. const
blocked_region
= ["KP", "SY", "PK", "CU"];
// 屏蔽 IP 地址. const
blocked_ip_address
= ["0.0.0.0", "127.0.0.1"];
// 镜像站是否开启 HTTPS. const
https
= true;
// 文本替换. const
replace_dict
= {
$upstream
: "$custom_domain", "//raw.githubusercontent.com": "" };
// 以下保持默认,不要动
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",
url
.
hostname
);
new_request_headers
.
set
("Referer",
url
.
hostname
);
let
original_response
= await
fetch
(
url
.
href
, {
method
:
method
,
headers
:
new_request_headers
,
}); 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
;
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");
const
content_type
=
new_response_headers
.
get
("content-type");
if (
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
;
}

贡献者

The avatar of contributor named as ruan-cat ruan-cat

页面历史

布局切换

调整 VitePress 的布局样式,以适配不同的阅读习惯和屏幕环境。

全部展开
使侧边栏和内容区域占据整个屏幕的全部宽度。
全部展开,但侧边栏宽度可调
侧边栏宽度可调,但内容区域宽度不变,调整后的侧边栏将可以占据整个屏幕的最大宽度。
全部展开,且侧边栏和内容区域宽度均可调
侧边栏宽度可调,但内容区域宽度不变,调整后的侧边栏将可以占据整个屏幕的最大宽度。
原始宽度
原始的 VitePress 默认布局宽度

页面最大宽度

调整 VitePress 布局中页面的宽度,以适配不同的阅读习惯和屏幕环境。

调整页面最大宽度
一个可调整的滑块,用于选择和自定义页面最大宽度。

内容最大宽度

调整 VitePress 布局中内容区域的宽度,以适配不同的阅读习惯和屏幕环境。

调整内容最大宽度
一个可调整的滑块,用于选择和自定义内容最大宽度。

聚光灯

支持在正文中高亮当前鼠标悬停的行和元素,以优化阅读和专注困难的用户的阅读体验。

ON开启
开启聚光灯。
OFF关闭
关闭聚光灯。