WEB

省钱秘笈之巧用Cloudflare免费做个镜像网站

偶然看到一个利用 Cloudflare Workers 做镜像的方法,无须购买服务器了,留作备用。
GitHub 项目:https://github.com/Siujoeng-Lau/Workers-Proxy

  1. 如果已经注册了 Cloudflare 账号,直接在左上 Products->Workers,没有就注册一个账号再说。
  2. 填写一个唯一子域名,Set up
  3. 选择免费版:
  4. 点击 Create a Worker 创建一个 Worker:
  5. 自动生成一串名称,有 hello world 示例代码:
  6. 删除示例,拷贝下方代码,看预览,保存部署:

    // 代理网站.
    const upstream = 'www.google.com'
    
    // 代理网站的目录.
    const upstream_path = '/'
    
    // 手机用户代理网站.
    const upstream_mobile = 'www.google.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',
        '//google.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;
    }
  7. 返回可重命名,这时就可以直接访问 WorkerName.Subdomain.workers.dev 了:
  8. 觉得域名太长不太好记,可以用自己的域名,前提是要在 cloudflare 解析,选择域名,点击 Workers->Add router
  9. Routesubdomain.yourdomain.com/*Worker 选择前面的部署:
  10. 在域名 DNS 解析里新建一个 CNAME 记录指向 WorkerName.Subdomain.workers.dev,等待生效后就可以用自己的域名访问了:
  11. 有时候会出现下面这个界面,等一会或者换个浏览器再看看:
微信扫一扫,向我赞赏

微信扫一扫,向我赞赏

回复

  1. jv th jv th
    Chrome 80 10

    请问,如何代理youtube呢?刚刚我安装您的脚本,Google都替换youtube,结果网页只有轮廓显示,无法看到画面。

    1. harry harry
      Chrome 80 10

      视频网站估计够呛,大概是内容链接太复杂了吧,我也不懂

  2. Sam.Z Sam.Z
    Firefox 74 10

    在公司看不到图片,这样的意思岂不是相当于通过CF来实现访问某些不可描述的网站,相当方便呀~ 等回家试试

    1. harry harry
      Chrome 80 10

      我一直拿GitHub当图库,现在好像不行了啊

This is just a placeholder img.