尝试在边缘运行 JavaScript

什么是边缘计算

边缘运算(Edge computing),又译为边缘计算,是一种分散式运算的架构,将应用程序、数据资料与服务的运算,由网络中心节点,移往网络逻辑上的边缘节点来处理。边缘计算将原本完全由中心节点处理大型服务加以分解,切割成更小与更容易管理的部分,分散到边缘节点去处理。边缘节点更接近于用户终端装置,可以加快资料的处理与传送速度,减少延迟。在这种架构下,资料的分析与知识的产生,更接近于数据资料的来源,因此更适合处理大数据。

OpenStack(是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目)社区的定义概念:

边缘计算是为应用开发者和服务提供商在网络的边缘侧提供云服务和IT环境服务;目标是在靠近数据输入或用户的地方提供计算、存储和网络带宽”。

章鱼理论秒懂边缘计算

章鱼理论:用 “ 脚 “ 解决问题的边缘计算!

作为无脊椎动物中智商最高的一种动物,章鱼拥有巨量的神经元,但60%分布在章鱼的八条腿(腕足)上,脑部仅有40%。

也就是说:

警告:本文从以下开始跑题。

== 需要M03-GLORIA程序特殊访问权限 ==

正在读取资料。请稍等…….

[拒绝访问]
[该数据已被删除]

正在读取备份。请稍等…….

本博客边缘计算的搭建方案

本博客目前采用Vercel、Cloudflare、GithubPages多线部署,未来可能会考虑添加██████等其他线路。笔者在此解释Cloudflare线路的边缘计算部署方案。

正如你所见,静态页面托管存储在Github仓库██████中,并开启GitHub Pages服务,使用Cloudflare Workers实现边缘计算处理逻辑,LeanCloud数据库存储网站动态数据。

笔者在这里只谈部署思路,由于███████████████████████████████████,相信应该不会有人愿意开源公开自己的后端程序,安全策略以及██████████████████████等等。

实现网站镜像

目前Cloudflare线路即为GithubPages的镜像站,我不说相信你也可以看出来,当然我也可以随时切换为Vercel或者██████或者██████的镜像站。

在网络边缘拦截用户请求,并修改请求中的request.url.hostname,将对用户请求的域解析替换为原始真实URL,实现隐藏真实网络基础设施的目的。

具体实现可以查阅相关文档

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
/**
* An object with different URLs to fetch
* @param {Object} ORIGINS
*/
const ORIGINS = {
"starwarsapi.yourdomain.com": "swapi.co",
"google.yourdomain.com": "google.com",
}

async function handleRequest(request) {
const url = new URL(request.url)
// Check if incoming hostname is a key in the ORIGINS object
if (url.hostname in ORIGINS) {
const target = ORIGINS[url.hostname]
url.hostname = target
// If it is, proxy request to that third party origin
return fetch(url.toString(), request)
}

// Otherwise, process request as normal
return fetch(request)
}

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

隐藏前端API密钥

由于调用数据库API需要使用AppIDAppKey

而直接将他们写在前端页面存在安全风险,因此笔者将数据库API密钥直接写在了Cloudflare Worker中。

以本站的评论系统为例,在前端页面插入伪造的API密钥以作混淆,下图一看就知道是伪造的密钥

在网络边缘拦截用户请求,判断请求合法性,动态更改请求标头替换为真实的API密钥,并向后端数据库转发请求,实现数据交互时隐藏API密钥。

具体实现可以查阅相关文档

自定义防火墙规则

从 CF-IPCountry HTTP 标头检索 IP 地理位置信息,以判断访问者合法性██████████████████,对于非法访问者████████████████████████████。笔者配合使用████████████数据库实现动态████████████████████████。

How does Cloudflare handle HTTP Request headers?

Configuring Cloudflare IP Geolocation

记录请求日志

由于Cloudflare Workers没有导入依赖包的功能██████████████████,因此笔者使用Leancloud数据库的REST API发送 HTTP 请求来与 数据库 进行交互。

Cloudflare Workers默认在事件的response发送完成后结束边缘的相关进程,这里笔者使用event.waitUntil(promise Promise),延长事件的生存期,而不会阻止事件的response发送。使用此方法可以通知运行时以等待需要比正常的发送响应时间更长的时间运行的任务(例如,日志记录,对第三方服务的分析,流和缓存)。

将所有请求记录到数据库中,以便需要时调查取证或者█████████。

HTTP2 server push

多路复用,是HTTP/2众多协议优化中最令人振奋的特性,它大大降低了网络延迟对性能的影响,而对于资源之间的依赖关系导致的“延迟”,Server Push则提供了手动优化方案。

通常,只有在浏览器请求某个资源的时候,服务器才会向浏览器发送该资源。Server Push则允许服务器在收到浏览器的请求之前,主动向浏览器推送资源。比如说,网站首页引用了一个CSS文件。浏览器在请求首页时,服务器除了返回首页的HTML之外,可以将其引用的 CSS文件也一并推给客户端。

本站在返回的请求中添加HTTP 标头实现HTTP2 server push。

1
2
3
if(request.headers.get("content-type")=="text/html; charset=utf-8"){
response.headers.set("Link", "</css/style.css>; rel=preload; as=style,</js/app.js>; rel=preload; as=script, <https://cdn.jsdelivr.net>; rel=preconnect; crossorigin, <https://cdn.jsdelivr.net>; rel=dns-prefetch")
}

具体实现可以查阅相关文档

CORS header proxy

由于██████████████████需要前端实现跨域,可以直接添加 HTTP 标头实现。

1
2
3
4
5
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, HEAD, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
}

具体实现可以查阅相关文档

其他应用

更多Examples

[文件已删除]

搭建其他镜像站

上面介绍镜像自己的博客,如法炮制,你也可以镜像其他网站,例如Github、█████████、█████████、█████████等,请勿用于非法用途,否则后果自负。

下面是一个随便在百度中搜索到的脚本,几乎随便一搜都可以找到它,大家不会都用一个吧。

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
// 你想镜像的站点
const upstream = 'zh.wikipedia.org'

// 针对移动端适配站点,没有就和保持和上面一致
const upstream_mobile = 'zh.wikipedia.org'

// 禁止某些地区访问
const blocked_region = []

// 禁止自访问
const blocked_ip_address = ['0.0.0.0', '127.0.0.1']

// 你想镜像的站点
const replace_dict = {
'$upstream': '$custom_domain',
'//zh.wikipedia.org': ''
}

// 剩下的就不用管了
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_host = url.host;

if (url.protocol == 'http:') {
url.protocol = 'https:'
response = Response.redirect(url.href);
return response;
}

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

url.host = upstream_domain;

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.href);

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_host);
} 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 workers blog

cloudflare-worker-blog

一个在Github上的开源实例,██████████████████████████████████████████████████
██████████████████████████████████Cloudflare workers + Github 实现的动态博客系统█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████。

jsproxy

jsproxy一个基于浏览器端 JS 实现的在线代理,████████████████████████████████████████

█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████。

项目主要用于以下技术的研究:

  • 网站镜像 / 沙盒化
  • 钓鱼网站检测技术
  • 前端资源访问加速

█████████████████████████████,否则█████████████。

加速 Google Analytics

cloudflare-workers-async-google-analytics

The Cloudflare Workers implementation of an async Google Analytics.

██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████。

以上代码,请勿将其用于非法用途,否则后果自负。

严禁未经授权的人员进行访问

肇事者将被监控,定位并处理

评论