阅读视图

发现新文章,点击刷新页面。

免费海外网站CDN加速,让全球访问更畅快

全球网站加速新选择,免费CDN让访问更畅快

在如今这个信息化快速发展的时代,网站的访问速度直接影响到用户体验与业务转化率。尤其对于海外市场的企业和个人站长来说,如何提升跨国访问的速度,成为了一项亟待解决的挑战。传统的网络架构常常面临着跨国访问时延长、带宽瓶颈、服务器负载过重等问题,这些都会导致网站加载缓慢,用户体验大打折扣。

因此,越来越多的企业开始采用CDN(内容分发网络)加速技术,借助CDN加速节点在全球范围内的分布,将内容就近分发给终端用户,从而提高网站访问速度、降低延迟。特别是对于需要面向海外市场的站点,CDN加速技术显得尤为重要。

不过,企业在选择CDN服务时,往往会面临高昂的费用和复杂的技术配置问题,这使得不少中小型企业望而却步。现在,随着市场上逐渐出现了免费的CDN加速服务,越来越多的站长和企业开始尝试这种高效、低成本的方式来解决海外网站加速的难题。

推荐CDN

免费CDN加速服务,让海外网站访问更迅速

“免费海外网站CDN加速”,这个关键词听起来可能让一些人感到惊讶。的确,一些提供免费CDN服务的平台已经逐渐成熟,能够为用户提供可靠的加速效果。通过全球分布的加速节点,用户的访问请求能够被快速路由到距离最近的服务器节点,从而大大提升网页加载速度。

免费CDN服务的优势不仅体现在费用上,更在于其便捷的部署方式。许多免费CDN平台提供简单易用的界面,站长或管理员可以在几分钟内完成CDN加速的配置,无需复杂的技术背景或繁琐的设置。对于非技术背景的用户来说,这无疑是一个巨大的便利。

免费CDN服务一般都具有全球节点分布,可以针对不同的地区(如欧美、亚洲等)进行智能路由和加速,使得海外用户访问国内网站时,也能享受到和本地用户几乎相同的加载速度。特别是对于那些拥有海外市场需求的电商、博客、企业官网等网站来说,免费CDN加速无疑是拓展市场、提高用户体验的利器。

如何选择适合的免费CDN服务?

面对众多的免费CDN服务,如何选择一个合适的平台呢?以下几个方面可以作为参考:

全球节点分布:选择一个节点覆盖范围广的免费CDN服务,尤其是覆盖欧美、亚太等重要市场的节点,可以确保海外用户的访问体验大大提升。

易用性:简单易用的管理面板和清晰的配置步骤是选择CDN服务时的重要考虑因素。许多免费CDN平台提供简单的DNS配置或插件安装,降低了使用门槛。

服务稳定性:虽然是免费的CDN服务,但其稳定性和性能也必须得到保证。可以通过查看其他用户的评价,了解平台的可靠性。

流量限制:有些免费CDN服务对于流量和带宽会有一定的限制,选择时要注意是否满足自己网站的流量需求。

通过对这些方面的考量,你可以选择一个适合自己网站的免费CDN加速服务,最大化提高网站的访问速度和用户体验。

免费CDN加速带来的优化效果

使用免费CDN加速服务之后,海外网站的访问速度会有显著提升。对于用户来说,最直接的感受就是网页加载速度的提升,特别是在全球范围内访问时,页面几乎瞬间加载,流畅度极高。这里,我们可以详细分析一下CDN加速带来的几大优势:

降低网站加载延迟

网站加载延迟一直是影响用户体验的关键因素之一。特别是对于面向海外市场的网站,网络延迟问题会更加突出。通过将网站内容缓存到全球各地的CDN节点,用户的请求被自动路由到距离其最近的节点,从而大幅度减少了延迟,保证了快速加载。

提升全球访问速度

对于跨国网站,尤其是那些需要面向欧美、亚洲等多个地区的用户的企业而言,全球访问速度的提升尤为关键。通过选择免费的CDN加速服务,可以在全球范围内提高用户的访问体验,增强客户的黏性,进一步促进产品销售和品牌推广。

减轻服务器负担

传统网站在流量高峰时,容易出现服务器负载过重、响应速度慢等问题。而通过CDN加速,用户的请求被分散到多个CDN节点上,减轻了源服务器的负担,有效避免了高峰期的流量冲击。CDN服务商通常会提供DDoS防护等安全防护功能,增加网站的安全性,避免受到恶意攻击。

提高SEO排名

网站的加载速度对SEO排名有着直接的影响。搜索引擎(尤其是Google)会根据网站的加载速度来评估其质量,并在排名中给予一定的加分。通过使用CDN加速,网站加载速度得到显著提升,有助于提升网站的搜索引擎排名,增加曝光度和流量。

避免地域性封锁与限制

某些国家和地区对特定网站存在地域封锁或访问限制的问题。借助CDN服务,站点的内容可以绕过一些地域性限制,实现跨地域访问无障碍。这一点对一些内容敏感的行业尤其重要。

如何开始使用免费CDN加速服务?

开始使用免费的海外网站CDN加速服务其实非常简单,下面是大致的步骤:

选择合适的免费CDN平台

根据自己的需求,选择一个适合的免费CDN加速服务平台。常见的免费CDN平台有Cloudflare、Fastly、Sucuri等,它们在全球范围内拥有丰富的加速节点,并提供简单的配置方式。

注册并配置域名

在平台上注册账号,并按照平台的指引进行域名配置。通常情况下,你需要将域名的DNS指向CDN平台提供的DNS服务器。

调整缓存设置与规则

配置完DNS后,你可以根据自己的需要,设置缓存策略、SSL证书、访问控制等选项。这些设置将帮助你进一步优化网站性能和安全性。

监控与优化

配置完CDN加速后,务必定期检查网站的加载速度、访问日志等信息,了解加速效果。根据具体情况进行必要的调整,进一步优化网站性能。

总结

无论是小型企业还是个人站长,免费的海外网站CDN加速服务都为他们提供了一个轻松提升网站全球访问速度的机会。通过全球分布的加速节点、智能流量调度与缓存策略,不仅能有效提升用户体验,还能降低服务器负载、提高网站安全性。使用CDN加速服务是每一个网站提升访问速度和用户满意度的重要步骤。选择合适的免费CDN服务,让你的网站无论在国内还是海外都能更迅速、更稳定地运行。

免费利用cloudflare的ZeroTrust进行内网穿透

前言

因为有些web项目需要在本地运行然后进行测试,所以就需要用到内网穿透,但是大多数的内网穿透服务都需要付费,于是就想到了cloudflare。

教程

1.首先注册并登录cloudflare

2.托管一个域名到cloudflare,这里就不细讲了不懂的自行百度

3.点击zero trust

4.然后选择套餐为免费的,这时候提示需要绑定信用卡。

5.直接返回到主界面就可以跳过绑定这一步骤

6.选择Networks中的tunnels

7.点击Add a tunnel

8.选择cloudflare并且点击next

9.在输入框中填写名称,随便填写即可并且点击save tunnel

10.选择系统并且安装提示安装cloudflare,最后点击Next

11.在Subdomain填写子域名,Domain选择托管的域名,path选择目录,Type选择方式,本次为http,URL为localhost:端口

12.最后点击save tunnel,这样就算部署成功了。

13.比如https://127.0.0.1:5678/1.txt就可以更改为https://xx.xxxx.com/1.txt

结语

cloudflare作为最大的免费服务提供商,内网穿透速度也非常快,再说了免费的东西要什么自行车。

使用cloudflare workers遇到的小问题

前言

今天闲来无事部署了几个小项目

教程

1.不能部署

很多朋友在填写好workers代码后会发现右上角的部署并不能点击,其实可以返回到项目首页然后再编辑代码,点击弹窗中的save就可以了。

2.报错函数名

因为今天部署的代码中有个需要用到kv存储,所以在workers代码中就有kv存储的名称,但是当时不知道,所以鼓捣了很久。

比如statuslive.get和statuslive.put,其中statuslive就是用到的kv存储的名称,我们就需要根据这个来设定kv存储的名称。

3.自定义路由

今天在给项目自定义域的时候发现自定义路由的时候提示需要有包含域名的子域名,但是我子域名名称中都有域名了还是提示一直添加失败。

暂未能够解决,如果谁知道解决方法请在下方留言,所以最终只能使用了自定义域。

注册免费域名并托管到cloudflare

前言

今天逛博客的时候逛到友链淇云博客发现了一个好玩的文章,就是教我们怎么注册免费域名并且托管到cloudflare。

于是我就自己尝试了一下

教程

1.首先打开us.kg官网注册一个账号,点击下方的sign up

图片[1]-新锐博客

2.打开美国人身份生成网站,网站不要关闭

图片[2]-新锐博客

3.按照上面生成的地址填写信息

图片[3]-新锐博客

4.打开邮箱,找到新收到的邮件并且验证

图片[4]-新锐博客

5.按照下图选择验证方式

图片[5]-新锐博客

6.到Fake SID中生成学生卡ID

图片[6]-新锐博客

7.截图并且保存学生卡到电脑

8.上传学生卡

图片[7]-新锐博客

9.登录网站并且注册域名

10.登录cloudflare绑定域名

图片[8]-新锐博客

11.返回网站填写好cloudflare的给予的DNS服务器就行了

CloudFlare自选IP并配置dns,达到加速目的

前言

网上有不少的cloudflare优选ip的cname,但是别人的终归是别人能不能自己搭建一个呢?

开源地址

Github:https://github.com/ddgth/cf2dns

教程

此次教程使用的是自己服务器搭建

1.安装运行脚本所需依赖

pip install -r requirements.txt

2.登录腾讯云后台或者阿里云后台,获取 SecretId、SecretKey,如果使用阿里云DNS,注意需要添加DNS控制权限AliyunDNSFullAccess

3.将脚本下载到本地修改cf2dns.py中的SecretId、SecretKey

4.修改脚本中域名配置信息,可配置多个域名和多个子域名,注意选择DNS服务商

5.(可选)从商店购买KEY,当然也可以用脚本中自带的,区别是脚本中自带的KEY是历史优选的Cloudflare IP(也可以从这个网站查到IP的信息),而购买的KEY是15分钟内获取到的最新的Cloudflare IP。

6.运行程序,如果能够正常运行可以选择cron定时执行(建议15分钟执行一次)

python cf2dns.py

使用Cloudflare搭建docker镜像站

前言

之前介绍的docker镜像站都是别人的不是自己的,于是就可以用cloudflare搭建属于自己的docker镜像站。

教程

1.首先要注册一个Cloudflare账号。

2.Cloudflare账号下域名的一级域名,不会的自行百度如何修改DNS记录以便托管到cloudflare。

3.注意 Worker 每天每免费账号有次数限制,为10万次。每分钟为1000次。

4.本教程来源于Github开源项目cf-workers-docker

方法一

1.登录cloudflare官网,选择workers和pages,创建workers

2.编辑worker.js,将如下代码放到其中并且在右上角选择部署。

// _worker.js

// Docker镜像仓库主机地址
let hub_host = 'registry-1.docker.io'
// Docker认证服务器地址
const auth_url = 'https://auth.docker.io'
// 自定义的工作服务器地址
let workers_url = 'https://你的域名'

// 根据主机名选择对应的上游地址
function routeByHosts(host) {
		// 定义路由表
	const routes = {
		// 生产环境
		"quay": "quay.io",
		"gcr": "gcr.io",
		"k8s-gcr": "k8s.gcr.io",
		"k8s": "registry.k8s.io",
		"ghcr": "ghcr.io",
		"cloudsmith": "docker.cloudsmith.io",
		
		// 测试环境
		"test": "registry-1.docker.io",
	};

	if (host in routes) return [ routes[host], false ];
	else return [ hub_host, true ];
}

/** @type {RequestInit} */
const PREFLIGHT_INIT = {
	// 预检请求配置
	headers: new Headers({
		'access-control-allow-origin': '*', // 允许所有来源
		'access-control-allow-methods': 'GET,POST,PUT,PATCH,TRACE,DELETE,HEAD,OPTIONS', // 允许的HTTP方法
		'access-control-max-age': '1728000', // 预检请求的缓存时间
	}),
}

/**
 * 构造响应
 * @param {any} body 响应体
 * @param {number} status 响应状态码
 * @param {Object<string, string>} headers 响应头
 */
function makeRes(body, status = 200, headers = {}) {
	headers['access-control-allow-origin'] = '*' // 允许所有来源
	return new Response(body, { status, headers }) // 返回新构造的响应
}

/**
 * 构造新的URL对象
 * @param {string} urlStr URL字符串
 */
function newUrl(urlStr) {
	try {
		return new URL(urlStr) // 尝试构造新的URL对象
	} catch (err) {
		return null // 构造失败返回null
	}
}

function isUUID(uuid) {
	// 定义一个正则表达式来匹配 UUID 格式
	const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
	
	// 使用正则表达式测试 UUID 字符串
	return uuidRegex.test(uuid);
}

async function nginx() {
	const text = `
	<!DOCTYPE html>
	<html>
	<head>
	<title>Welcome to nginx!</title>
	<style>
		body {
			width: 35em;
			margin: 0 auto;
			font-family: Tahoma, Verdana, Arial, sans-serif;
		}
	</style>
	</head>
	<body>
	<h1>Welcome to nginx!</h1>
	<p>If you see this page, the nginx web server is successfully installed and
	working. Further configuration is required.</p>
	
	<p>For online documentation and support please refer to
	<a href="https://nginx.org/">nginx.org</a>.<br/>
	Commercial support is available at
	<a href="https://nginx.com/">nginx.com</a>.</p>
	
	<p><em>Thank you for using nginx.</em></p>
	</body>
	</html>
	`
	return text ;
}

export default {
	async fetch(request, env, ctx) {
		const getReqHeader = (key) => request.headers.get(key); // 获取请求头

		let url = new URL(request.url); // 解析请求URL
		workers_url = `https://${url.hostname}`;
		const pathname = url.pathname;
		const hostname = url.searchParams.get('hubhost') || url.hostname; 
		const hostTop = hostname.split('.')[0];// 获取主机名的第一部分
		const checkHost = routeByHosts(hostTop);
		hub_host = checkHost[0]; // 获取上游地址
		const fakePage = checkHost[1];
		console.log(`域名头部: ${hostTop}n反代地址: ${hub_host}n伪装首页: ${fakePage}`);
		const isUuid = isUUID(pathname.split('/')[1].split('/')[0]);
		
		const conditions = [
			isUuid,
			pathname.includes('/_'),
			pathname.includes('/r'),
			pathname.includes('/v2/user'),
			pathname.includes('/v2/orgs'),
			pathname.includes('/v2/_catalog'),
			pathname.includes('/v2/categories'),
			pathname.includes('/v2/feature-flags'),
			pathname.includes('search'),
			pathname.includes('source'),
			pathname === '/',
			pathname === '/favicon.ico',
			pathname === '/auth/profile',
		];

		if (conditions.some(condition => condition) && (fakePage === true || hostTop == 'docker')) {
			if (env.URL302){
				return Response.redirect(env.URL302, 302);
			} else if (env.URL){
				if (env.URL.toLowerCase() == 'nginx'){
					//首页改成一个nginx伪装页
					return new Response(await nginx(), {
						headers: {
							'Content-Type': 'text/html; charset=UTF-8',
						},
					});
				} else return fetch(new Request(env.URL, request));
			}
			
			const newUrl = new URL("https://registry.hub.docker.com" + pathname + url.search);

			// 复制原始请求的标头
			const headers = new Headers(request.headers);

			// 确保 Host 头部被替换为 hub.docker.com
			headers.set('Host', 'registry.hub.docker.com');

			const newRequest = new Request(newUrl, {
					method: request.method,
					headers: headers,
					body: request.method !== 'GET' && request.method !== 'HEAD' ? await request.blob() : null,
					redirect: 'follow'
			});

			return fetch(newRequest);
		}

		// 修改包含 %2F 和 %3A 的请求
		if (!/%2F/.test(url.search) && /%3A/.test(url.toString())) {
			let modifiedUrl = url.toString().replace(/%3A(?=.*?&)/, '%3Alibrary%2F');
			url = new URL(modifiedUrl);
			console.log(`handle_url: ${url}`)
		}

		// 处理token请求
		if (url.pathname.includes('/token')) {
			let token_parameter = {
				headers: {
					'Host': 'auth.docker.io',
					'User-Agent': getReqHeader("User-Agent"),
					'Accept': getReqHeader("Accept"),
					'Accept-Language': getReqHeader("Accept-Language"),
					'Accept-Encoding': getReqHeader("Accept-Encoding"),
					'Connection': 'keep-alive',
					'Cache-Control': 'max-age=0'
				}
			};
			let token_url = auth_url + url.pathname + url.search
			return fetch(new Request(token_url, request), token_parameter)
		}

		// 修改 /v2/ 请求路径
		if (/^/v2/[^/]+/[^/]+/[^/]+$/.test(url.pathname) && !/^/v2/library/.test(url.pathname)) {
			url.pathname = url.pathname.replace(//v2//, '/v2/library/');
			console.log(`modified_url: ${url.pathname}`)
		}

		// 更改请求的主机名
		url.hostname = hub_host;

		// 构造请求参数
		let parameter = {
			headers: {
				'Host': hub_host,
				'User-Agent': getReqHeader("User-Agent"),
				'Accept': getReqHeader("Accept"),
				'Accept-Language': getReqHeader("Accept-Language"),
				'Accept-Encoding': getReqHeader("Accept-Encoding"),
				'Connection': 'keep-alive',
				'Cache-Control': 'max-age=0'
			},
			cacheTtl: 3600 // 缓存时间
		};

		// 添加Authorization头
		if (request.headers.has("Authorization")) {
			parameter.headers.Authorization = getReqHeader("Authorization");
		}

		// 发起请求并处理响应
		let original_response = await fetch(new Request(url, request), parameter)
		let original_response_clone = original_response.clone();
		let original_text = original_response_clone.body;
		let response_headers = original_response.headers;
		let new_response_headers = new Headers(response_headers);
		let status = original_response.status;

		// 修改 Www-Authenticate 头
		if (new_response_headers.get("Www-Authenticate")) {
			let auth = new_response_headers.get("Www-Authenticate");
			let re = new RegExp(auth_url, 'g');
			new_response_headers.set("Www-Authenticate", response_headers.get("Www-Authenticate").replace(re, workers_url));
		}

		// 处理重定向
		if (new_response_headers.get("Location")) {
			return httpHandler(request, new_response_headers.get("Location"))
		}

		// 返回修改后的响应
		let response = new Response(original_text, {
			status,
			headers: new_response_headers
		})
		return response;
	}
};

/**
 * 处理HTTP请求
 * @param {Request} req 请求对象
 * @param {string} pathname 请求路径
 */
function httpHandler(req, pathname) {
	const reqHdrRaw = req.headers

	// 处理预检请求
	if (req.method === 'OPTIONS' &&
		reqHdrRaw.has('access-control-request-headers')
	) {
		return new Response(null, PREFLIGHT_INIT)
	}

	let rawLen = ''

	const reqHdrNew = new Headers(reqHdrRaw)

	const refer = reqHdrNew.get('referer')

	let urlStr = pathname

	const urlObj = newUrl(urlStr)

	/** @type {RequestInit} */
	const reqInit = {
		method: req.method,
		headers: reqHdrNew,
		redirect: 'follow',
		body: req.body
	}
	return proxy(urlObj, reqInit, rawLen)
}

/**
 * 代理请求
 * @param {URL} urlObj URL对象
 * @param {RequestInit} reqInit 请求初始化对象
 * @param {string} rawLen 原始长度
 */
async function proxy(urlObj, reqInit, rawLen) {
	const res = await fetch(urlObj.href, reqInit)
	const resHdrOld = res.headers
	const resHdrNew = new Headers(resHdrOld)

	// 验证长度
	if (rawLen) {
		const newLen = resHdrOld.get('content-length') || ''
		const badLen = (rawLen !== newLen)

		if (badLen) {
			return makeRes(res.body, 400, {
				'--error': `bad len: ${newLen}, except: ${rawLen}`,
				'access-control-expose-headers': '--error',
			})
		}
	}
	const status = res.status
	resHdrNew.set('access-control-expose-headers', '*')
	resHdrNew.set('access-control-allow-origin', '*')
	resHdrNew.set('Cache-Control', 'max-age=1500')

	// 删除不必要的头
	resHdrNew.delete('content-security-policy')
	resHdrNew.delete('content-security-policy-report-only')
	resHdrNew.delete('clear-site-data')

	return new Response(res.body, {
		status,
		headers: resHdrNew
	})
}

3.进入网站选择workers路由

4.填写需要的子域名比如hub.xxxx.com和部署完成的workers项目

5.进入网站的DNS解析,添加hub.xxxx.com的A解析,可以指向8.8.8.8

方法二

1.访问cf-workers-docker,fork项目到自己仓库。

2.登录cloudflare找到workers和pages,选择pages关联github。

3.选择fork的cf-workers-docke项目,一键创建pages。

4.进入项目设置找到自定义域,填写比如hub.xxxx.com域名,最后会自动cname解析到生成项目地址。

设置

方式一

修改文件 /etc/docker/daemon.json(如果不存在则创建)

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://hub.xxxx.com"]  # 请替换为您自己的Worker自定义域名
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

方式二

命令拉取镜像,比如

docker pull hub.xxxx.com/yidadaa/chatgpt-next-web

结语

自此搭建完成,因为有访问量的限制,所以最好是自己用不要外放出来。

利用cloudflare给域名进行301重定向

前言

有些人注册域名的时候注册了很多,有很多很久没用了放在那太可惜,所以可以利用cloudflare给域名进行301重定向到新域名。

教程

1.首先登录 Cloudflare 的控制面板

2.将域名的DNS记录更改为 Cloudflare

3.进入 “Page Rules” 页面,创建一条页面规则。

4.选择URL转发,选择301重定向并且填写需要跳转的域名和被跳转的域名

结语

这是一种无需服务器的方法,但是众所周知cloudflare是没有国内节点的,所以访问速度有点慢,不过对于跳转足够用了。

Docker 搭建轻量高颜值个人导航页面

前言

Flare是一款轻量、快速、美观个人导航页面,适用于 HomeLab 或其它注重私密的场景。

可支持 Docker 一键部署,维护方便。

无任何数据库依赖。应用数据完全开放透明。

支持在线编辑。支持 x86 及常见的 ARM 设备。应用资源消耗很低。

截图

图片[1]-新锐博客

特点

服务资源消耗极低,可以跑在任何规格的机器上。

程序页面性能较好,渲染速度更快,支持同时渲染大量书签。

使用声明的配置来进行导航内容管理,无需担心数据迁移问题。

简化了天气数据的获取方式,不再需要申请天气网站的 API_KEY,避免不必要的成本开销。

内置大量风格统一、高质量的矢量图标,确保界面长期耐看。

默认使用免登陆的模式,避免了 HomeLab、本地使用的用户有额外登录操作。

教程

1.命令搭建
docker run -d -p 5005:5005 -v `pwd`/app:/app soulteary/flare
2.docker-compose搭建
version: '3.6'

services:
  flare:
    image: soulteary/flare
    restart: always
    # 默认无需添加任何参数,如有特殊需求
    # 可阅读文档 https://github.com/soulteary/docker-flare/blob/main/docs/advanced-startup.md
    command: flare
    # 启用账号登陆模式
    # command: flare --nologin=0
    # environment:
      # 如需开启用户登陆模式,需要先设置 `nologin` 启动参数为 `0`
      # 如开启 `nologin`,未设置 FLARE_USER,则默认用户为 `flare`
      # - FLARE_USER=flare
      # 指定你自己的账号密码,如未设置 `FLARE_USER`,则会默认生成密码并展示在应用启动日志中
      # - FLARE_PASS=your_password
      # 是否开启“使用向导”,访问 `/guide`
      # - FLARE_GUIDE=1
    ports:
      - 5005:5005
    volumes:
      - ./app:/app

然后执行就行

docker-compose up -d

 

利用cloudflare给github加速

前言

众所周知,github的访问总是会不尽如人意,有时候就会很快有时候就会访问不了,有大佬就想到了用cloudflare结合自定义域给github加速

教程

  1. 首先注册一个cloudflare的账号,然后创建一个workers。
  2. 填写完名称以后部署完成之后,点击快速编辑并将如下代码放到js中
// 你要镜像的网站.
const upstream = "www.github.com";
// 镜像网站的目录,比如你想镜像某个网站的二级目录则填写二级目录的目录名,镜像 google 用不到,默认即可.
const upstream_path = "/";
// 镜像站是否有手机访问专用网址,没有则填一样的.
const upstream_mobile = "www.github.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",
  "//github.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;
}

 

改动此代码还可以加速其他网站

最后,添加路由就行(需要将域名托管在 cf 上)

结语

如果有空闲域名可以尝试部署一下,这样访问github等网站就比较方便了。

利用cloudflare和Telegraph搭建免费图床

前言

在搭建网站的过程中不可避免的要上传不少图片,但是如果都放在本地的话访问就会很慢,如果放在存储对象里就可能有被盗刷的风险,于是一个完美的解决方案就来了。

那就是依靠cloudflare的免费额度和github开源项目Telegraph。

教程

首先去cloudflare官网申请一个账号,顺便github也申请一个。

然后打开项目地址:https://github.com/cf-pages/Telegraph-Image,把项目fork到你自己的项目里。再完成接下来的步骤

1、进入Workers和Pages概述界面

在Cloudflare主页,点击左侧Workers和Pages——>概述菜单

2、连接Github项目

首先,点击右上角创建应用程序,跳转到创建应用程序页面,并切换到Pages界面:

点击页面中的连接到Git按钮,在弹出界面中选择Github,并点击连接Github按钮:

之后,Cloudflare会自动引导你到Github授权页面,如果没有登录Github,则会先到登录界面:

接着,选择Only Select repositories,并选择上面fork好的项目,然后点击Install & Authorize按钮,确认完成授权和开始安装:

最后,Github可能会要求你输入账号密码,以确认上面的授权。输入你的Github密码并Confirm即可:

3、部署到Cloudflare

上面确认授权后,会从Github自动跳回到Cloudflare中,继续开始后续的部署设置。

首选,选中上面授权好的Github项目,点击开始设置

项目名称可以改成你自己喜欢的,生产分支建议保持默认的main,其他的不要动:

拉到页面下面,点击保存并部署,等待Pages自动部署项目:

当看到成功提示时,表示我们的图床已经部署完成了。此时Cloudflare自动分配了一个默认的域名,直接点击即可打开图床的上传页面:

如下图,Telegraph的上传界面非常简洁,直接点击选中上传图片或视频按钮即可进行上传:

设置图床

以上过程就完成在Cloudflare中部署Telegraph图床系统了,不过这时候还存在一些问题,包括如何管理用户上传的内容?如何绑定自己的域名?如何审查用户上传的内容是否违规?下面一一来解答。

一、配置管理后台

Telegraph的后台管理功能和登录验证功能默认都是关闭的,我们仅需对部署的Pages项目进行一些设置就可以开启这些功能了。

1、创建KV命名空间

打开Workers和Pages——>KV管理界面,然后点击右上角创建命名空间按钮,创建一个名为img_url的命名空间:

2、查看Pages项目

回到Workers和Pages——>概述界面,找到上面部署好的Telegraph项目,直接点击名称,进入项目的详情页面:

3、绑定KV命名空间

点击设置-函数,拉到页面的下面,找到KV命名空间绑定模块:

点击添加绑定按钮,将变量名称KV命名空间均设置为img_url,然后保存:

4、设置管理后台登录验证

切换到环境变量页面,点击制作中的添加变量按钮,添加两个环境变量:

变量名分别是BASIC_USERBASIC_PASS,分别代表管理员的用户名和密码,然后保存:

当然,你也可以不设置这两个变量,这时候管理后台就是无需验证即可登录。但是你可以结合Cloudflare Access服务实现支持邮件验证码、Microsoft、Github等第三方帐号登录方式,更加灵活强大。如果使用Cloudflare Access,则需要对/admin/api/manage/*两个路径进行保护。由于不是本文的重点,笔者就不展开了。

5、重新部署

做完以上的操作并不会立即生效,需要重新部署下系统才可以。

重新部署也非常简单,点击查看详细信息,在项目部署详情信息页面的右上角有个管理部署,点击其中的重新部署,等待重新部署完成即可。

6、登录管理后台

以上步骤操作完就实现了图床系统的管理后台功能和登录验证功能的设置,可以输入图床域名+/admin路径,就能打开管理后台了。例如:https://telegraph-image-xxx.pages.dev/admin:

打开后,在弹出框中输入上面设置好的用户名和密码即可:

管理界面有点简陋,可以看到图片的状态信息,也可以对图片进行黑/白名单设置或删除操作:

二、绑定自定义域名

Cloudflare自动分配的域名不好记(当然,如果你能忍受就可以不自定义),我们可以设置成我们自己的域名,方便使用,设置也很简单。

1、进入Pages项目

同样先进入项目页面,切换到自定义域页面:

2、添加自定义域

点击设置自定义域,输入你自己想用的二级域名,并点击继续按钮:

3、激活自定义域

可以看到Cloudflare将自动在域名DNS中添加一个CNAME解析记录,将自定义域名指向默认分配的域名。直接点击激活域按钮,然后等待验证即可:

4、使用自定义域

自定义域验证完成后,而且自动帮你配置好了SSL证书,非常贴心了。此时就可以使用新的域名访问你的图床系统了。例如

https://imghub.yourdomain.com/

三、开启内容审查

图床中上传的图片或视频默认是不经过审查的,上传后就可以被访问了。作为一个上传无需登录的图床,没有审核还是很危险的。如果被人恶意上传了不法内容,作为域名持有人,躺枪荣获"银手镯"就不妙了。Telegraph支持使用“moderatecontent”来进行自动内容审查,下面进行简单的配置就可以开启这项功能,强烈建议开启

1、获取API Key

打开"moderatecontent.com"网站,点击SIGN UP,输入你的邮箱,点击SUBMIT,界面上就直接为你生成API Key,复制并保存下来:

2、设置环境变量

与上文中设置管理后台登录验证的步骤一样,到项目的设置——>环境界面中,添加一个环境变量,名称为:ModerateContentApiKey,值就是上面获得的API Key。

3、重新部署

同样的,做完以上的操作并不会立即生效,需要重新部署下系统才可以。

特别说明:开启图片审查后,因为审查需要时间,首次的图片加载将会变得缓慢,审查完成后的图片加载由于存在缓存,就不会受到影响了。

更新图床系统

如果Telegraph-Image项目更新了,如何才能更新自己部署的图床呢?

很简单,如果项目更新后,需要添加新的KV命名空间或环境变量,则先在Cloudflare的项目中配置好。然后到你自己的Github中,在Telegraph-Image项目页面上点击Sync fork——>Update branch即可。

更新完成后,稍等一会,等Cloudflare Pages那边检测到你的仓库更新了之后就会自动部署最新的代码了。

利用CDN和CF实现全球加速

挺久没更新了,小水一下

往往我们需要使用CDN进行网站加速、防护,但是很多CDN是对标一个地区进行优化,例如亚太CDN,那么对于北美等其他地域则是优化不太友好,同时遇到攻击如果屏蔽海外,也可能会出现一些问题,然后就利用使用双CDN加速,国内用户走国内CDN加速,国外用户走CloudflareCDN加速

image|690x378

Cloudflare : 毫无疑问,这家CDN提供商是地表最强的,他们提供免费CDN、免备案CDN和高防御CDN服务。在国内,他们秒杀一线厂商

国内资本CDN :主流的CDN提供商主要专注于优化国内线路,提供按量、按次、按时段等不同收费方式。除了基础CDN服务外,还提供各种额外收费项目。优点在于提供快速可靠的服务

添加境外解析

一句概括,如果你已经配置了站点,下滑找到Cloudflare 名称服务器,记录NS值、然后前往你的域名运营商添加记录。

image|690x291

你猜猜我为什么要放语言在旁边

记录类型选NS ,主机记录填写博客前缀如:www ,解析线路选境外 ,记录值填写上一步记下的NS值 ,确认无误后点击确认 即可。

image|690x291

回到Cloudflare的DNS 页面,添加一个A记录 ,同样输入博客名前缀www ,IP地址填写主机地址 ,代理状态的小云朵一定要点亮为橙色 ,至此博客国外访问加速已经设置完毕。

image|690x66

添加默认解析

顾名思义,就是正常的去添加你的CDN,解析线路选择默认即可,首先在你的CDN添加好站点

image|690x299

设置好防御策略,然后前往域名添加CNAME解析即可

image|690x30

❌