Note-52760-1

Token ID: 1

ERC-721 1 Transfers

Metadata

{
  "title": "我是如何解决 jsDelivr 在国内被污染的?",
  "tags": [
    "post",
    "Cloudflare",
    "jsDelivr"
  ],
  "summary": "早在2021年12月20日,jsDelivr 在中国大陆地区的 ICP 备案被吊销,且随后的服务在中国大陆地区极不稳定,严重拖慢了网页的速度。 由于 jsDelivr 被封锁,导致了原来使用 jsDelivr 的 CDN 服务的网页速度缓慢,多数功能不正常。要解决这个问题…",
  "sources": [
    "xlog"
  ],
  "external_urls": [
    "https://xlog.yct.ee/jsDelivrOnCloudflare"
  ],
  "date_published": "2023-04-06T12:20:14.000Z",
  "content": "---\ntitle: 我是如何解决 jsDelivr 在国内被污染的?\nabbrlink: 'jsDelivr'\ntags:\n  - Cloudflare\ncategories: 技术\nmathjax: true\ndate: 2023-04-06 12:20:14\ndescription: 使用Cloudflare Worker为jsDelivr搭建反向代理服务\nsticky: 2\n---\n早在2021年12月20日,jsDelivr 在中国大陆地区的 ICP 备案被吊销,且随后的服务在中国大陆地区极不稳定,严重拖慢了网页的速度。\n\n由于 jsDelivr 被封锁,导致了原来使用 jsDelivr 的 CDN 服务的网页速度缓慢,多数功能不正常。要解决这个问题,要么更换 CDN,要么给 jsDelivr 套上一层反向代理。这里博主采用了 Cloudflare Worker。\n# 新建 Worker\n登录到 Cloudflare 控制台,点击侧栏的 Workers,新建服务。\n\n![gh](https://cdn.yct.ee/gh/BarryYangi/ObsStaticData@main/obsidian/16807536030001yhgo9.png)\n\n在创建页面填入你自己的服务名称。\n![gh](https://cdn.yct.ee/gh/BarryYangi/ObsStaticData@main/obsidian/1680753650000qwb9pf.png)\n\n创建后将转入资源页面。\n![gh](https://cdn.yct.ee/gh/BarryYangi/ObsStaticData@main/obsidian/1680753684000wpls1p.png)\n\n# 部署\n点击“快速编辑”,在代码框内复制以下代码:\n\n```javascript\n// 替换成你想镜像的站点\nconst upstream = 'cdn.jsdelivr.net'\n \n// 如果那个站点有专门的移动适配站点,否则保持和上面一致\nconst upstream_mobile = 'cdn.jsdelivr.net'\n \nconst blocked_region = ['KP','RU']\n \nconst blocked_ip_address = ['0.0.0.0', '127.0.0.1']\n \nconst replace_dict = {\n    '$upstream': '$custom_domain',\n    '//cdn.jsdelivr.net': ''\n}\n \n//以下内容都不用动\naddEventListener('fetch', event => {\n    event.respondWith(fetchAndApply(event.request));\n})\n \nasync function fetchAndApply(request) {\n \n    const region = request.headers.get('cf-ipcountry').toUpperCase();\n    const ip_address = request.headers.get('cf-connecting-ip');\n    const user_agent = request.headers.get('user-agent');\n \n    let response = null;\n    let url = new URL(request.url);\n    let url_host = url.host;\n \n    if (url.protocol == 'http:') {\n        url.protocol = 'https:'\n        response = Response.redirect(url.href);\n        return response;\n    }\n \n    if (await device_status(user_agent)) {\n        upstream_domain = upstream\n    } else {\n        upstream_domain = upstream_mobile\n    }\n \n    url.host = upstream_domain;\n \n    if (blocked_region.includes(region)) {\n        response = new Response('Access denied: WorkersProxy is not available in your region yet.', {\n            status: 403\n        });\n    } else if(blocked_ip_address.includes(ip_address)){\n        response = new Response('Access denied: Your IP address is blocked by WorkersProxy.', {\n            status: 403\n        });\n    } else{\n        let method = request.method;\n        let request_headers = request.headers;\n        let new_request_headers = new Headers(request_headers);\n \n        new_request_headers.set('Host', upstream_domain);\n        new_request_headers.set('Referer', url.href);\n \n        let original_response = await fetch(url.href, {\n            method: method,\n            headers: new_request_headers\n        })\n \n        let original_response_clone = original_response.clone();\n        let original_text = null;\n        let response_headers = original_response.headers;\n        let new_response_headers = new Headers(response_headers);\n        let status = original_response.status;\n \n        new_response_headers.set('access-control-allow-origin', '*');\n        new_response_headers.set('access-control-allow-credentials', true);\n        new_response_headers.delete('content-security-policy');\n        new_response_headers.delete('content-security-policy-report-only');\n        new_response_headers.delete('clear-site-data');\n \n        const content_type = new_response_headers.get('content-type');\n        if (content_type.includes('text/html') && content_type.includes('UTF-8')) {\n            original_text = await replace_response_text(original_response_clone, upstream_domain, url_host);\n        } else {\n            original_text = original_response_clone.body\n        }\n \n        response = new Response(original_text, {\n            status,\n            headers: new_response_headers\n        })\n    }\n    return response;\n}\n \nasync function replace_response_text(response, upstream_domain, host_name) {\n    let text = await response.text()\n \n    var i, j;\n    for (i in replace_dict) {\n        j = replace_dict[i]\n        if (i == '$upstream') {\n            i = upstream_domain\n        } else if (i == '$custom_domain') {\n            i = host_name\n        }\n \n        if (j == '$upstream') {\n            j = upstream_domain\n        } else if (j == '$custom_domain') {\n            j = host_name\n        }\n \n        let re = new RegExp(i, 'g')\n        text = text.replace(re, j);\n    }\n    return text;\n}\n \nasync function device_status (user_agent_info) {\n    var agents = [\"Android\", \"iPhone\", \"SymbianOS\", \"Windows Phone\", \"iPad\", \"iPod\"];\n    var flag = true;\n    for (var v = 0; v < agents.length; v++) {\n        if (user_agent_info.indexOf(agents[v]) > 0) {\n            flag = false;\n            break;\n        }\n    }\n    return flag;\n}\n```\n\n保存并部署后,你的反向代理就生效了。\n# 自定义域名\n但是不幸的是在国内 `.workers.dev` 后缀的域名现在也被污染了,所以你需要自己绑定一个域名在国内才能正常访问。\n先购买一个域名,然后将其 DNS 服务商转到 cloudflare。随后来到我们刚刚新建的 Workers 管理页面点击触发器->自定义域->添加自定义域,输入你想绑定的域名即可。\n\n# 测试\n使用时,将原来的 `cdn.jsdelivr.net` 域名替换为您的 Worker 或者博主提供的 Worker 就可以了。如:\n```javascript\nhttps://cdn.jsdelivr.net/gh/BarryYangi/ObsStaticData/obsidian/168069442100071iy8i.png\n```\n将`cdn.jsdelivr.net`替换为我们的Worker:\n```javascript\nhttps://jsdelivr-cdn.2059484047.workers.dev/gh/BarryYangi/ObsStaticData/obsidian/168069442100071iy8i.png\n```\n\n这样,就能保证较为稳定的使用 jsDelivr 的服务了。\n\nJust enjoy it.",
  "attributes": [
    {
      "value": "jsDelivrOnCloudflare",
      "trait_type": "xlog_slug"
    }
  ]
}