前言

本文原本为解决博客上时钟API出现的跨域CORS问题,但通过Servicerwoker优化后便不在存在此问题.

故本文仅做记录📝.

本文代码来着于Gihub项目cloudflare-cors-anywhere

设置Workers

点击 创建服务

image-20220819135839030

名称随便.例如cors

image-20220819140004978

点击 快速编辑

image-20220819140057525

复制以下代码.

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
/*
CORS Anywhere as a Cloudflare Worker!
(c) 2019 by Zibri (www.zibri.org)
email: zibri AT zibri DOT org
https://github.com/Zibri/cloudflare-cors-anywhere
*/

/*
whitelist = [ "^http.?://www.zibri.org$", "zibri.org$", "test\\..*" ]; // regexp for whitelisted urls
*/

blacklist = [ ]; // regexp for blacklisted urls
whitelist = [ ".*" ]; // regexp for whitelisted origins

function isListed(uri,listing) {
var ret=false;
if (typeof uri == "string") {
listing.forEach((m)=>{
if (uri.match(m)!=null) ret=true;
});
} else { // decide what to do when Origin is null
ret=true; // true accepts null origins false rejects them.
}
return ret;
}

addEventListener("fetch", async event=>{
event.respondWith((async function() {
isOPTIONS = (event.request.method == "OPTIONS");
var origin_url = new URL(event.request.url);

function fix(myHeaders) {
// myHeaders.set("Access-Control-Allow-Origin", "*");
myHeaders.set("Access-Control-Allow-Origin", event.request.headers.get("Origin"));
if (isOPTIONS) {
myHeaders.set("Access-Control-Allow-Methods", event.request.headers.get("access-control-request-method"));
acrh = event.request.headers.get("access-control-request-headers");
//myHeaders.set("Access-Control-Allow-Credentials", "true");

if (acrh) {
myHeaders.set("Access-Control-Allow-Headers", acrh);
}

myHeaders.delete("X-Content-Type-Options");
}
return myHeaders;
}
var fetch_url = decodeURIComponent(decodeURIComponent(origin_url.search.substr(1)));

var orig = event.request.headers.get("Origin");

var remIp = event.request.headers.get("CF-Connecting-IP");

if ((!isListed(fetch_url, blacklist)) && (isListed(orig, whitelist))) {

xheaders = event.request.headers.get("x-cors-headers");

if (xheaders != null) {
try {
xheaders = JSON.parse(xheaders);
} catch (e) {}
}

if (origin_url.search.startsWith("?")) {
recv_headers = {};
for (var pair of event.request.headers.entries()) {
if ((pair[0].match("^origin") == null) &&
(pair[0].match("eferer") == null) &&
(pair[0].match("^cf-") == null) &&
(pair[0].match("^x-forw") == null) &&
(pair[0].match("^x-cors-headers") == null)
) recv_headers[pair[0]] = pair[1];
}

if (xheaders != null) {
Object.entries(xheaders).forEach((c)=>recv_headers[c[0]] = c[1]);
}

newreq = new Request(event.request,{
"redirect": "follow",
"headers": recv_headers
});

var response = await fetch(fetch_url,newreq);
var myHeaders = new Headers(response.headers);
cors_headers = [];
allh = {};
for (var pair of response.headers.entries()) {
cors_headers.push(pair[0]);
allh[pair[0]] = pair[1];
}
cors_headers.push("cors-received-headers");
myHeaders = fix(myHeaders);

myHeaders.set("Access-Control-Expose-Headers", cors_headers.join(","));

myHeaders.set("cors-received-headers", JSON.stringify(allh));

if (isOPTIONS) {
var body = null;
} else {
var body = await response.arrayBuffer();
}

var init = {
headers: myHeaders,
status: (isOPTIONS ? 200 : response.status),
statusText: (isOPTIONS ? "OK" : response.statusText)
};
return new Response(body,init);

} else {
var myHeaders = new Headers();
myHeaders = fix(myHeaders);

if (typeof event.request.cf != "undefined") {
if (typeof event.request.cf.country != "undefined") {
country = event.request.cf.country;
} else
country = false;

if (typeof event.request.cf.colo != "undefined") {
colo = event.request.cf.colo;
} else
colo = false;
} else {
country = false;
colo = false;
}

return new Response(
"CLOUDFLARE-CORS-ANYWHERE\n\n" +
"Source:\nhttps://github.com/Zibri/cloudflare-cors-anywhere\n\n" +
"Usage:\n" + origin_url.origin + "/?uri\n\n" +
"Donate:\nhttps://paypal.me/Zibri/5\n\n" +
"Limits: 100,000 requests/day\n" +
" 1,000 requests/10 minutes\n\n" +
(orig != null ? "Origin: " + orig + "\n" : "") +
"Ip: " + remIp + "\n" +
(country ? "Country: " + country + "\n" : "") +
(colo ? "Datacenter: " + colo + "\n" : "") + "\n" +
((xheaders != null) ? "\nx-cors-headers: " + JSON.stringify(xheaders) : ""),
{status: 200, headers: myHeaders}
);
}
} else {

return new Response(
"Create your own cors proxy</br>\n" +
"<a href='https://github.com/Zibri/cloudflare-cors-anywhere'>https://github.com/Zibri/cloudflare-cors-anywhere</a></br>\n" +
"\nDonate</br>\n" +
"<a href='https://paypal.me/Zibri/5'>https://paypal.me/Zibri/5</a>\n",
{
status: 403,
statusText: 'Forbidden',
headers: {
"Content-Type": "text/html"
}
});
}
}
)());
});

粘贴代码替换存在的代码,然后保存并部署即可.

image-20220819140232471

Tips

代码中可以设置请求的黑白名单

当然也可以设置为whitelist = [ ".*" ],这样的任何人都可以使用了

然而免费版本的每天只有10万次请求,如果用的人多了很容易就用完了,所以还是建议大家设置 whitelist.

用法

首先,查看路由地址

image-20220819140834229

假定我们的API链接为: https://xx.xxx.com/cityjson?ie=utf-8

那么请求的链接为: https://cors.lanyundev.workers.dev/?https://xx.xxx.com/cityjson?ie=utf-8

如果大家不想弄上面的设置,可以直接白嫖我的这个Workers资源https://cors.lanyundev.workers.dev/?.我现在有需求了😂

不过还是建议自己搭建,因为如果以后我有需求了会对其下线.