CloudFlare Worker Script to setup URL Shortener Service
You can optionally add your own aliases. If not, an random string would be assigned.
addEventListener('fetch', event => { | |
event.respondWith(handleRequest(event.request)) | |
}) | |
const html404 = `<!DOCTYPE html> | |
<body> | |
<h1>404 Not Found.</h1> | |
<p>The url you visit is not found.</p> | |
</body>` | |
const htmlBody = ` | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>URL Shortener</title> | |
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" | |
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> | |
<style> | |
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;700;900&display=swap'); | |
*, | |
body { | |
font-family: 'Poppins', sans-serif; | |
font-weight: 400; | |
-webkit-font-smoothing: antialiased; | |
text-rendering: optimizeLegibility; | |
-moz-osx-font-smoothing: grayscale; | |
} | |
html, | |
body { | |
height: 100%; | |
background-color: #152733; | |
overflow: hidden; | |
} | |
.form-holder { | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
align-items: center; | |
text-align: center; | |
min-height: 100vh; | |
} | |
.form-holder .form-content { | |
position: relative; | |
text-align: center; | |
display: -webkit-box; | |
display: -moz-box; | |
display: -ms-flexbox; | |
display: -webkit-flex; | |
display: flex; | |
-webkit-justify-content: center; | |
justify-content: center; | |
-webkit-align-items: center; | |
align-items: center; | |
padding: 60px; | |
} | |
.form-content .form-items { | |
border: 3px solid #fff; | |
padding: 40px; | |
display: inline-block; | |
width: 100%; | |
min-width: 540px; | |
-webkit-border-radius: 10px; | |
-moz-border-radius: 10px; | |
border-radius: 10px; | |
text-align: left; | |
-webkit-transition: all 0.4s ease; | |
transition: all 0.4s ease; | |
} | |
.form-content h3 { | |
color: #fff; | |
text-align: left; | |
font-size: 28px; | |
font-weight: 600; | |
margin-bottom: 5px; | |
} | |
.form-content h3.form-title { | |
margin-bottom: 30px; | |
} | |
.form-content p { | |
color: #fff; | |
text-align: left; | |
font-size: 17px; | |
font-weight: 300; | |
line-height: 20px; | |
margin-bottom: 30px; | |
} | |
.form-content label, | |
.was-validated .form-check-input:invalid~.form-check-label, | |
.was-validated .form-check-input:valid~.form-check-label { | |
color: #fff; | |
} | |
.form-content input[type=text], | |
.form-content input[type=password], | |
.form-content input[type=email], | |
.form-content select { | |
width: 100%; | |
padding: 9px 20px; | |
text-align: left; | |
border: 0; | |
outline: 0; | |
border-radius: 6px; | |
background-color: #fff; | |
font-size: 15px; | |
font-weight: 300; | |
color: #8D8D8D; | |
-webkit-transition: all 0.3s ease; | |
transition: all 0.3s ease; | |
margin-top: 16px; | |
} | |
.btn-primary { | |
background-color: #6C757D; | |
outline: none; | |
border: 0px; | |
box-shadow: none; | |
} | |
.btn-primary:hover, | |
.btn-primary:focus, | |
.btn-primary:active { | |
background-color: #495056; | |
outline: none !important; | |
border: none !important; | |
box-shadow: none; | |
} | |
.form-content textarea { | |
position: static !important; | |
width: 100%; | |
padding: 8px 20px; | |
border-radius: 6px; | |
text-align: left; | |
background-color: #fff; | |
border: 0; | |
font-size: 15px; | |
font-weight: 300; | |
color: #8D8D8D; | |
outline: none; | |
resize: none; | |
height: 120px; | |
-webkit-transition: none; | |
transition: none; | |
margin-bottom: 14px; | |
} | |
.form-content textarea:hover, | |
.form-content textarea:focus { | |
border: 0; | |
background-color: #ebeff8; | |
color: #8D8D8D; | |
} | |
.mv-up { | |
margin-top: -9px !important; | |
margin-bottom: 8px !important; | |
} | |
.invalid-feedback { | |
color: #ff606e; | |
} | |
.valid-feedback { | |
color: #2acc80; | |
} | |
</style> | |
<script> | |
const submitURL = () => { | |
document.getElementById("status").innerHTML = "Creating short url" | |
//await call url for new shortlink and return | |
long = document.getElementById("url").value; | |
short = document.getElementById("shortid").value; | |
const object = { | |
longURL: long, | |
shortURL: short | |
} | |
fetch('/', { | |
method: "POST", | |
body: JSON.stringify(object), | |
headers: { | |
'Content-Type': 'application/json' | |
} | |
}) | |
.then(data => data.text()) | |
.then(data => { | |
console.log('ready') | |
document.getElementById("status").innerHTML = data | |
}) | |
} | |
</script> | |
</head> | |
<body> | |
<div class="form-body"> | |
<div class="row"> | |
<div class="form-holder"> | |
<div class="form-content"> | |
<div class="form-items"> | |
<h3 class="text-center mx-auto">The URL Shortener</h3> | |
<p class="text-center mx-auto">Shorten Big URLs</p> | |
<div class="col-md-12"> | |
<input class="form-control" type="text" id="url" placeholder="Enter the URL" required> | |
</div> | |
<div class="col-md-12"> | |
<input class="form-control" type="text" id="shortid" | |
placeholder="Provide an Alias (Optional)"> | |
</div> | |
<div class="form-button mt-4 text-center mx-auto "> | |
<button id="submit" onclick="submitURL()" class="btn btn-primary">Shorten</button> | |
</div> | |
<div class=" col-md-12 mt-5 text-center mx-auto"> | |
<label class="form-check-label" id="status"></label> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" | |
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" | |
crossorigin="anonymous"></script> | |
</body> | |
</html> | |
` | |
/** | |
* Respond with hello worker text | |
* @param {Request} request | |
*/ | |
async function randomString(len) { | |
ããlen = len || 6; | |
ããlet $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; | |
ãã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 handleRequest(request) { | |
if (request.method === "POST") { | |
const urls = await request.json() | |
let urlb = JSON.parse(JSON.stringify(urls)) | |
longURL = urlb.longURL | |
shortURL = urlb.shortURL | |
if ( shortURL == "" ){ | |
shortURL = await randomString() | |
} | |
if(!await checkURL(longURL)){ | |
return new Response(" Illegal URL Detected. Please Enter a Valid URL ") | |
} | |
let is_exist = await URL_SPACE.get(shortURL) | |
if (is_exist == null) { | |
await URL_SPACE.put(shortURL, longURL) | |
return new Response("Your short URL: http://localhost:8787/" + shortURL) | |
} | |
else { | |
return new Response(" Duplicate Alias Detected. Enter a different Alias. ") | |
} | |
} | |
if (request.method === "GET") { | |
let shortCode = request.url.replace(/https:\/\/.+?\//g, "") | |
shortCode = shortCode.replace(/http:\/\/.+?\//g, "") | |
if (shortCode !== "") { | |
let redirectTo = await URL_SPACE.get(shortCode) | |
if (redirectTo != null) { | |
return Response.redirect(redirectTo, 301) | |
} | |
else { | |
return new Response(html404, { | |
headers: { | |
"content-type": "text/html;charset=UTF-8", | |
}, | |
status: 404 | |
}) | |
} | |
} | |
else { | |
return new Response(htmlBody, { | |
headers: { 'content-type': 'text/html' }, | |
}) | |
} | |
} | |
} |
You need to paste this script in the Index.JS
file of your CloudFlare Worker
The Service : https://short-linker.lucifergene.workers.dev/
You can visit the repository from below:
You can reach out on my Twitter, Instagram, or LinkedIn if you need more help. I would be more than happy.
If you have come up to this, do drop an â€ïž if you liked this article.
Top comments (0)