让我们用Node.js创建一个URL扩展器。
是的,我们创建的是 URL 扩展器,而不是 URL 缩短器。
有很多工具,例如bitly、shorturl等,可以帮助我们将冗长杂乱的 URL 转换为简短美观的 URL。例如,https://www.youtube.com/c/AngleBrace可以转换为shorturl.at/asIW4。
但网址扩展器会起到相反的作用。
所以我们可以利用它从短链接获取原始长链接。
但为什么?
有些不法分子可以把病毒下载链接(例如https://www.badsite.com/virus.exe )缩短成https://shorturl.at/wDPZ5。这样一来,仅凭短链接就无法判断这个链接会下载病毒。所以,为了防止病毒和不良网站,我们有时可以使用网址扩展器。
我们开始吧。
你也可以在 YouTube 上观看视频版本。
首先,创建一个项目文件夹,然后在终端中打开它。接着运行命令npm init -y创建一个新的 Node.js 项目。这也会生成一个package.json 文件。 之后,我们需要安装一些包。我们需要express和request,所以运行命令来安装它们 。我们还需要安装 nodemon 作为开发依赖项,这样每次修改 JavaScript 文件时就无需重新运行。所以运行命令来安装它。 现在,在package.json文件中,我们将删除测试脚本并创建一个启动脚本。
npm i express requestnpm i nodemon -D
{
"name": "url_expander",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "nodemon index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"request": "^2.88.2"
},
"devDependencies": {
"nodemon": "^2.0.15"
}
}
好了,现在我们来创建一个index.js文件,并搭建一个基本的 NodeJS 和 Express 项目。
const express = require('express')
const app = express()
app.use(express.static('public'))
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
})
app.listen(3000, () => {
console.log('Server is running on port 3000')
})
现在我们可以创建一个公共文件夹。在这个文件夹里,我们将创建 HTML、CSS 和 JS 文件。所以我们的文件夹结构大概是这样的。 好的,现在让我们在 HTML 文件中编写一些标记。我们将有三个主要元素。
- 一个可以输入短链接的输入框
- 按钮会发送请求以展开 URL。
- 我们将在此处显示展开后的 URL。
<!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">
<link rel="stylesheet" href="style.css">
<title>Node JS URL Expander</title>
</head>
<body>
<div class="container">
<div class="input-box">
<input type="text" id="input" placeholder="Enter Short URL">
<button id="expand-btn">expand</button>
</div>
<a href="" id="result"></a><!-- Expanded URl will be shown here -->
</div>
<script src="main.js"></script>
</body>
</html>
现在让我们在style.css 文件中设置它的样式。
*{
margin: 0;
padding: 0;
}
html, body{
height: 100%;
}
body{
background-color: rgb(239, 131, 84);
display: flex;
justify-content: center;
align-items: center;
}
.container{
width: 320px;
padding: 3em;
background-color: rgba(255, 255, 255, 0.3);
}
.input-box{
height: 35px;
display: flex;
}
input{
flex-grow: 1;
}
button{
background-color: rgb(233, 95, 35);
color: white;
text-transform: uppercase;
}
input, button{
padding: 0 1em;
display: block;
border: none;
outline: none;
}
#result{
color: white;
word-break: break-all;
font-size: 1.2em;
text-align: center;
display: block;
margin-top: 1em;
}
现在,如果我们运行命令启动服务器npm start并访问,localhost:3000应该会看到这个页面。 太好了!现在,在我们的main.js 文件中,让我们实现点击按钮时向服务器发送请求并显示响应的功能。
/expand
const input = document.querySelector('#input')
const expandBtn = document.querySelector('#expand-btn')
const result = document.querySelector('#result')
expandBtn.addEventListener('click', () => {
// Initally set the result to loading
result.innerText = 'Loading ...'
fetch(`/expand`)
.then(res => res.text())
.then(text => {
// Display the result send from the server
result.innerText = text
})
.catch(err => {
console.log(err)
result.innerText = 'Error'
})
})
现在让我们在index.js 文件中创建/expand路由。
const express = require('express')
const app = express()
app.use(express.static('public'))
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
})
app.get('/expand', (req, res) => {
res.send("hello")
})
app.listen(3000, () => {
console.log('Server is running on port 3000')
})
所以现在如果我们点击按钮,它应该显示“hello”。好的,现在在我们的 main.js 中,当发送请求时,我们也把输入值作为查询参数发送。
/expand
const input = document.querySelector('#input')
const expandBtn = document.querySelector('#expand-btn')
const result = document.querySelector('#result')
expandBtn.addEventListener('click', () => {
result.innerText = 'Loading ...'
// passing the input value to the server as shortUrl query string
fetch(`/expand?shortUrl=${input.value}`)
.then(res => res.text())
.then(text => {
result.innerText = text
})
.catch(err => {
console.log(err)
result.innerText = 'Error'
})
})
现在我们可以在index.js中获取输入值了。
app.get('/expand', (req, res) => {
let shortUrl = req.query.shortUrl
res.send("hello")
})
现在,我们终于可以使用之前安装的request包来获取短链接的原始 URL 了。
const express = require('express')
const request = require('request')
const app = express()
app.use(express.static('public'))
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
})
app.get('/expand', (req, res) => {
let shortUrl = req.query.shortUrl
// If the shortUrl doesn't start with http, add add https:// in front of it
// So eg. example.com becomes https://example.com
if(!shortUrl.startsWith('http')) shortUrl = 'https://' + shortUrl
request({
url: shortUrl,
method: "HEAD",
followAllRedirects: true
},
(err, response, body) => {
if (err) {
console.log(err)
res.send("Error")
} else {
// Sending back the full url
res.send(response.request.href)
}
})
})
app.listen(3000, () => {
console.log('Server is running on port 3000')
})
现在我们的项目已经完成了。请输入一个短链接,例如shorturl.at/aoqyO,然后点击展开,它应该会显示完整的网址。
