Created
August 28, 2021 16:20
-
-
Save Lucifergene/9d3d805c7a6db23be58d4a4d11831b87 to your computer and use it in GitHub Desktop.
CloudFlare Worker Script for URL Shortener Service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' }, | |
}) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment