返回

如何用Cloudflare worker自建短链接服务

这里展示了在CloudFlare上面使用JS实现短链接服务

目录

# 如何用Cloudflare worker自建短链接服务

短链接又称短网址、短码,意思就是形式上比较短的网址,可以通过将一个普通的冗长的网址缩短生成一个新的较短的网址,便于分享传播。

短链接主要应用场景如下:

短信发送 短信里用短链接,可以极大减少字符,现在很多营销短信都是用的短网址。

社群推广 很多社区或社交网站,会屏蔽长链接。微博字数限制,公众号关键字链接限制等,短网址可以缩短字符,规避掉这些限制。

微信防屏蔽 微信里有各种屏蔽,用短链接可以避免暴露原有地址关键字,规避屏蔽。

活码 短网址是固定的,可以通过修改原链接达到变更地址的作用,此时不用去修改固定的短网址,短网址就相当于一个中间层。主要用于替换更换链接成本较高的地方,比如生成好的二维码等。

# 搭建

这里利用cloudflare workers提供的服务,免费版本每日100000次请求,对个人使用而言完全足够。

  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
const html404 = `<!DOCTYPE html>
<body>
  <h1>404 0.</h1>
  <p>0.</p>
</body>`

// const statichtml = "https://raw.githubusercontent.com/1x000/zdzy/main/duanlnk/index.html"


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)
    return objExp.test(str) && str[0] === 'h'
}
async function save_url (URL, shortStr) {
    console.log("shortStr:", shortStr)
    let random_key
    if (!shortStr) {
        random_key = await randomString()
    } else {
        random_key = shortStr
    }
    let is_exist = await LINKS.get(random_key)
    console.log(is_exist)
    if (is_exist == null) {
        // 正常,直接放入
        let stat = await LINKS.put(random_key, URL)
        if (typeof (stat) === "undefined") return random_key
        else return stat
    } else if (!shortStr) {
        // 生成的random_key重复了,递归调用
        return save_url(URL, null)
    } else
        // 自定义的路径已经存在了
        return -1

}
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(`{"msg":"0"}`, { status: 400, headers: { "Content-Type": "application/json" } })
        let random_key = await save_url(req["url"], req["shortStr"])
        console.log(random_key)
        // 放成功了
        if (Object.prototype.toString.call(random_key) === "[object String]")
            return new Response(`{"data":{"shortUrl":"${random_key}"}}`, { status: 200, headers: { "Content-Type": "application/json" } })
        // 自定义的路径重复了
        else if (random_key === -1)
            return new Response(`{"msg":"0"}`, { status: 400, headers: { "Content-Type": "application/json" } })
        // 没测试k-v满了之后会怎么样,如果有错的话put时应该会有返回(猜测(懒
        else return new Response(`{"msg":"0"}`, { status: 500, headers: { "Content-Type": "application/json" } })
    }
    const requestURL = new URL(request.url)
    // todo 规范路径的'/'
    const path = requestURL.pathname.toString().substring(1);
    console.log(path)
    if (!path) {

        const html = await fetch(statichtml)

        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和KV存储创建一个URL缩短服务的脚本。它允许用户输入一个长URL,然后得到一个可以重定向到原始URL的短URL。它还支持自定义短URL的路径。下面是一个如何使用这段代码的教程:

  1. 创建一个Cloudflare账户和一个Workers订阅。你可以使用免费计划,每天允许最多10万次请求。

  2. 在Workers控制台中创建一个KV命名空间,命名为LINKS。这个命名空间将用来存储短URL和长URL的映射关系。

  3. 在Workers控制台中创建一个Worker,将这段代码粘贴到编辑器中。你可以修改代码中的一些变量,比如html404和statichtml,来自定义404页面和首页的内容。

  4. 部署Worker,并选择一个域名,比如example.workers.dev。这个域名将作为你的URL缩短服务的地址。

  5. 访问你的域名,你应该看到一个简单的网页,有一个输入框和一个按钮。你可以在输入框中输入一个长URL,然后点击按钮,就会得到一个短URL。你也可以在按钮旁边的输入框中输入一个自定义的路径,来指定你想要的短URL。如果自定义的路径已经被占用了,你会收到一个错误提示。

  6. 你可以复制生成的短URL,并在浏览器中打开它,就会跳转到原始的长URL。你也可以分享这个短URL给其他人,让他们访问你想要分享的网页。

# 警告

如果你要公开使用的话其中的HTML注释一定要去掉,如果你需要私有化的话请注释,因为总有人会往里面放写非法链接,导致域名出事