一、托管域名
毋庸置疑,要使用CF的服务,首先要把域名托管到Cloudflare。
注册Cloudflare帐号,添加域名,按提示设置DNS为Cloudflare的DNS并等待生效即可。
因不是本文重点,这里不做过多阐述。
二、创建Workers KV
进入需要搭建短链接网站的域名,点击『Workers』。
出现如下界面,点击『管理KV命名空间』。
输入任意名称,点击添加。
上面的菜单,点击Workers,点击创建 Worker。
三、构建短链接网站
打开:https://github.com/xyTom/Url-Shorten-Worker/
如果要进行自定义,则登陆自己的账号,没有就注册一个。
登陆后,在这个项目右边,点击Fork。
点击index.js,复制其中的代码,粘贴到我们创建的worker中,并点击保存并部署:
代码是这样的:
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 |
const html404 = `<!DOCTYPE html> <body> <h1>404 Not Found.</h1> <p>The url you visit is not found.</p> </body>` async function randomString(len) { len = len || 6; let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/ let maxPos = $chars.length; let result = ''; for (i = 0; i < len; i++) { result += $chars.charAt(Math.floor(Math.random() * maxPos)); } return result; } async function checkURL(URL){ let str=URL; let Expression=/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/; let objExp=new RegExp(Expression); if(objExp.test(str)==true){ if (str[0] == 'h') return true; else return false; }else{ return false; } } async function save_url(URL){ let random_key=await randomString() let is_exist=await LINKS.get(random_key) console.log(is_exist) if (is_exist == null) return await LINKS.put(random_key, URL),random_key else save_url(URL) } async function handleRequest(request) { console.log(request) if (request.method === "POST") { let req=await request.json() console.log(req["url"]) if(!await checkURL(req["url"])){ return new Response(`{"status":500,"key":": Error: Url illegal."}`, { headers: { "content-type": "text/html;charset=UTF-8", "Access-Control-Allow-Origin":"*", "Access-Control-Allow-Methods": "POST", }, })} let stat,random_key=await save_url(req["url"]) console.log(stat) if (typeof(stat) == "undefined"){ return new Response(`{"status":200,"key":"/`+random_key+`"}`, { headers: { "content-type": "text/html;charset=UTF-8", "Access-Control-Allow-Origin":"*", "Access-Control-Allow-Methods": "POST", }, }) }else{ return new Response(`{"status":200,"key":": Error:Reach the KV write limitation."}`, { headers: { "content-type": "text/html;charset=UTF-8", "Access-Control-Allow-Origin":"*", "Access-Control-Allow-Methods": "POST", }, })} }else if(request.method === "OPTIONS"){ return new Response(``, { headers: { "content-type": "text/html;charset=UTF-8", "Access-Control-Allow-Origin":"*", "Access-Control-Allow-Methods": "POST", }, }) } const requestURL = new URL(request.url) const path = requestURL.pathname.split("/")[1] console.log(path) if(!path){ const html= await fetch("https://cdn.jsdelivr.net/gh/xyTom/Url-Shorten-Worker@gh-pages/index.html") return new Response(await html.text(), { headers: { "content-type": "text/html;charset=UTF-8", }, }) } const value = await LINKS.get(path) console.log(value) const location = value if (location) { return Response.redirect(location, 302) } // If request not in kv, return 404 return new Response(html404, { headers: { "content-type": "text/html;charset=UTF-8", }, status: 404 }) } addEventListener("fetch", async event => { event.respondWith(handleRequest(event.request)) }) |
四、绑定域名并解析
完场以上环节后,可以通过Cloudflare提供的链接,访问到短链接网站,当然,我们需要绑定自己的域名,实现构建短链接网站。
返回Workers界面,点击刚刚创建的worker。
依次设置并点击保存。
返回域名管理,依次选择,设置路由。
绑定到刚才的Woker,点击保存。
路由这里可以填:sangbian.com/*
点击顶部菜单,选择DNS,添加两条记录:
名称这里,一条填@,另一条填www(也可以不要这一条),地址填写8.8.8.8,保存即可。
等待生效后就能通过自己的域名访问。
五、自定义页面
在我们的Worker代码中,有其中一句:
1 |
const html= await fetch("https://cdn.jsdelivr.net/gh/xyTom/Url-Shorten-Worker@gh-pages/index.html") |
打开这个链接,复制其中的代码。
还记得刚才我们Fork了一份代码吗?去我们的项目中,创建一个html文件,文件名自定义,参考以下我的代码修改后保存:
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 |
<!doctype html> <html> <head> <meta http-equiv="content-type" content="txt/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css" integrity="sha256-L/W5Wfqfa0sdBNIKN9cG6QA5F2qx4qICmU2VgLruv9Y=" crossorigin="anonymous"> <title>126短链接 - 免费短链接</title> <style> * { margin: 0; padding: 0; cursor: default; } html, body { height: 100%; } body { display: -webkit-box; display: flex; -webkit-box-align: center; align-items: center; -webkit-box-pack: center; justify-content: center; vertical-align: center; flex-wrap: wrap; align-content: center; color: #2a2b2c; background-color: #ebedee; overflow: hidden; } .card { background-color: transparent; width: 768px; } .card-text { text-align: center; } .card-text > a { text-decoration: none; color: #007bff; } .card-text > a { cursor: pointer; } .form-control { cursor: auto; } @media (max-width: 769px) { .card { width: 80%; } } @media (max-width: 420px) { .card { width: 95%; } } @media (prefers-color-scheme: dark) { body { color: #d9d9d9; background: #1b1b1b; } .card { background-color: #252d38; } } </style> </head> <body> <div class="card"> <h5 class="card-header">生成短链接</h5> <div class="card-body"> <h5 class="card-title">请在此处粘贴长连接,并点击生成</h5> <div class="input-group mb-3"> <input type="text" class="form-control" placeholder="如:https:/blog.lanluo.cn" id="text"> <div class="input-group-append"> <button class="btn btn-primary" type="button" onclick='shorturl()' id="searchbtn">生成</button> </div> </div> <div class="card-text"> <a href="https://blog.lanluo.cn/" target="_self" style="color:#999">蓝洛水深</a> <a href="https://github.com/xyTom/Url-Shorten-Worker/" target="_self" style="color:#DDD">Github</a> </div> <p id="notice"></p> </div> </div> <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">已生成</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body" id="result">生成失败</div> <div class="modal-footer"> <button type="button" class="btn btn-primary" onclick='copyurl("result")' data-toggle="popover" data-placement="bottom" data-content="Copied!">复制</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.slim.min.js" integrity="sha256-pasqAKBDmFT4eHoN2ndd6lN370kFiGUFyTiUHWhU7k8=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/js/bootstrap.min.js" integrity="sha256-WqU1JavFxSAMcLP2WIOI+GB2zWmShMI82mTpLDcqFUg=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/url-shorten-worker@1.0.5/main.js" crossorigin="anonymous"></script> </body> </html> |
保存后,将对应的GitHub链接复制,创建jsdelivr的CDN链接,修改Worker代码中的链接为我们的CDN链接,即可。
比如,我们的GitHub链接是:
1 |
https://github.com/llssus/Url-Shorten-Worker/blob/main/main20211012.html |
那么Jsdelivr的CDN链接生成后就是:
1 |
https://cdn.jsdelivr.net/gh/llssus/Url-Shorten-Worker@main/main20211012.html |
即,我最终的代码是:
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 |
const html404 = `<!DOCTYPE html> <body> <h1>404 Not Found.</h1> <p>The url you visit is not found.</p> </body>` async function randomString(len) { len = len || 6; let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/ let maxPos = $chars.length; let result = ''; for (i = 0; i < len; i++) { result += $chars.charAt(Math.floor(Math.random() * maxPos)); } return result; } async function checkURL(URL){ let str=URL; let Expression=/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/; let objExp=new RegExp(Expression); if(objExp.test(str)==true){ if (str[0] == 'h') return true; else return false; }else{ return false; } } async function save_url(URL){ let random_key=await randomString() let is_exist=await LINKS.get(random_key) console.log(is_exist) if (is_exist == null) return await LINKS.put(random_key, URL),random_key else save_url(URL) } async function handleRequest(request) { console.log(request) if (request.method === "POST") { let req=await request.json() console.log(req["url"]) if(!await checkURL(req["url"])){ return new Response(`{"status":500,"key":": Error: Url illegal."}`, { headers: { "content-type": "text/html;charset=UTF-8", "Access-Control-Allow-Origin":"*", "Access-Control-Allow-Methods": "POST", }, })} let stat,random_key=await save_url(req["url"]) console.log(stat) if (typeof(stat) == "undefined"){ return new Response(`{"status":200,"key":"/`+random_key+`"}`, { headers: { "content-type": "text/html;charset=UTF-8", "Access-Control-Allow-Origin":"*", "Access-Control-Allow-Methods": "POST", }, }) }else{ return new Response(`{"status":200,"key":": Error:Reach the KV write limitation."}`, { headers: { "content-type": "text/html;charset=UTF-8", "Access-Control-Allow-Origin":"*", "Access-Control-Allow-Methods": "POST", }, })} }else if(request.method === "OPTIONS"){ return new Response(``, { headers: { "content-type": "text/html;charset=UTF-8", "Access-Control-Allow-Origin":"*", "Access-Control-Allow-Methods": "POST", }, }) } const requestURL = new URL(request.url) const path = requestURL.pathname.split("/")[1] console.log(path) if(!path){ const html= await fetch("https://cdn.jsdelivr.net/gh/llssus/Url-Shorten-Worker@main/main20211012.html") return new Response(await html.text(), { headers: { "content-type": "text/html;charset=UTF-8", }, }) } const value = await LINKS.get(path) console.log(value) const location = value if (location) { return Response.redirect(location, 302) } // If request not in kv, return 404 return new Response(html404, { headers: { "content-type": "text/html;charset=UTF-8", }, status: 404 }) } addEventListener("fetch", async event => { event.respondWith(handleRequest(event.request)) }) |
至此,短链接网站制作完成,不用服务器,不用空间,还自带CDN,除了10万的限额以外,一切都是那么的美好。
原创文章,作者:蓝洛水深,如若转载,请注明出处:https://blog.lanluo.cn/10356