」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用 Node.js 和 MongoDB 建立 URL 縮短應用程式

使用 Node.js 和 MongoDB 建立 URL 縮短應用程式

發佈於2024-07-30
瀏覽:158

Building a URL Shortener App with Node.js and MongoDB

建立 URL 縮短服務是深入使用 Node.js 和 MongoDB 進行全端開發的好方法。在本部落格中,我們將逐步介紹建立 URL 縮短器應用程式的過程,該應用程式允許使用者將長 URL 轉換為縮短版本並追蹤其使用情況。

先決條件

要學習本教程,您應該:

  • 已安裝 Node.js
  • JavaScript與Express.js基礎
  • MongoDB 資料庫(您可以使用 MongoDB Atlas 作為雲端解決方案)

項目設定

第 1 步:初始化項目

首先,為您的專案建立新目錄並使用 npm 對其進行初始化:

mkdir url-shortener-app
cd url-shortener-app
npm init -y

步驟2:安裝依賴項

接下來,安裝必要的依賴:

npm install express mongoose cors dotenv
npm install --save-dev nodemon

第三步:專案結構

建立以下資料夾結構:

url-shortener-app/
├── controllers/
│   └── urlController.js
├── models/
│   └── urlModel.js
├── routes/
│   └── urlRoutes.js
├── .env
├── index.js
├── package.json

建構後端

第 4 步:設定 Express 伺服器

在index.js檔案中,設定Express伺服器並連接到MongoDB:

const express = require('express');
const mongoose = require('mongoose');
const urlRoutes = require('./routes/urlRoutes');
const cors = require('cors');

const app = express();
app.use(express.json());

require("dotenv").config();

const dbUser = process.env.MONGODB_USER;
const dbPassword = process.env.MONGODB_PASSWORD;

// Connect to MongoDB
mongoose
    .connect(
        `mongodb srv://${dbUser}:${dbPassword}@cluster0.re3ha3x.mongodb.net/url-shortener-app`,
        { useNewUrlParser: true, useUnifiedTopology: true }
    )
    .then(() => {
        console.log("Connected to MongoDB database!");
    })
    .catch((error) => {
        console.error("Connection failed!", error);
    });

app.use(cors({
    origin: "*",
}));

app.get('/', (req, res) => {
    res.send('Welcome to URL Shortener API');
});

app.use('/api', urlRoutes);

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

在根目錄下建立.env文件,用於存放環境變數:

MONGODB_USER=yourMongoDBUsername
MONGODB_PASSWORD=yourMongoDBPassword

第 5 步:定義 URL 模型

在 models/urlModel.js 檔案中,定義 URL 的架構:

const mongoose = require('mongoose');

const urlSchema = new mongoose.Schema({
    originalUrl: { type: String, required: true },
    shortUrl: { type: String, required: true, unique: true },
    clicks: { type: Number, default: 0 },
    expirationDate: { type: Date },
    createdAt: { type: Date, default: Date.now },
});

module.exports = mongoose.model('Url', urlSchema);

第 6 步:建立路線

在routes/urlRoutes.js檔案中,定義API的路由:

const express = require('express');
const { createShortUrl, redirectUrl, getUrls, getDetails, deleteUrl } = require('../controllers/urlController');
const router = express.Router();

router.post('/shorten', createShortUrl);
router.get('/urls', getUrls);
router.get('/:shortUrl', redirectUrl);
router.get('/details/:shortUrl', getDetails);
router.delete('/delete/:shortUrl', deleteUrl);

module.exports = router;

第 7 步:實作控制器

在controllers/urlController.js檔案中,實作控制器功能:

const Url = require('../models/urlModel');

function generateUniqueId(length) {
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    for (let i = 0; i  {
    const { originalUrl } = req.body;
    const shortUrl = generateUniqueId(5);
    const urlRegex = new RegExp(/^(http|https):\/\/[^ "] $/);
    if (!urlRegex.test(originalUrl))
        return res.status(400).json('Invalid URL');
    const url = await Url.findOne({ originalUrl });
    if (url) {
        res.json(url);
        return;
    }
    const expirationDate = new Date();
    expirationDate.setDate(expirationDate.getDate()   7);
    const newUrl = new Url({ originalUrl, shortUrl, expirationDate });
    await newUrl.save();
    res.json(newUrl);
};

const redirectUrl = async (req, res) => {
    const { shortUrl } = req.params;
    const url = await Url.findOne({ shortUrl });
    if (!url || (url.expirationDate && url.expirationDate  {
    try {
        const urls = await Url.find({}).sort({ _id: -1 });
        res.json(urls);
    } catch (error) {
        res.status(500).json({ message: 'Server Error' });
    }
};

const getDetails = async (req, res) => {
    try {
        const { shortUrl } = req.params;
        const url = await Url.findOne({ shortUrl });
        if (url) {
            res.json(url);
        } else {
            res.status(404).json('URL not found');
        }
    } catch (error) {
        res.status(500).json({ message: 'Server Error' });
    }
};

const deleteUrl = async (req, res) => {
    try {
        const { shortUrl } = req.params;
        await Url.findOneAndDelete({ shortUrl });
        res.json('URL deleted');
    } catch (error) {
        res.status(500).json({ message: 'Server Error' });
    }
};

module.exports = { createShortUrl, redirectUrl, getDetails, getUrls, deleteUrl };

運行應用程式

使用下列指令啟動伺服器:

npm run dev

此指令將使用 Nodemon 啟動您的伺服器,當您變更程式碼時,Nodemon 會自動重新啟動伺服器。

結論

在本部落格中,我們使用 Node.js 和 MongoDB 建立了一個簡單的 URL 縮短器應用程式。該應用程式允許用戶縮短 URL、追蹤其使用情況並透過到期日期進行管理。該專案是學習全端開發的一個很好的起點,並且可以透過使用者身份驗證、自訂 URL 別名等其他功能進行擴充。

探索程式碼

存取 GitHub 儲存庫以詳細探索程式碼。


您可以根據您的喜好隨意定制博客,並在需要時提供更多詳細信息或解釋。

版本聲明 本文轉載於:https://dev.to/manthanank/building-a-url-shortener-app-with-nodejs-and-mongodb-bhh?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 對象擬合:IE和Edge中的封面失敗,如何修復?
    對象擬合:IE和Edge中的封面失敗,如何修復?
    To resolve this issue, we employ a clever CSS solution that solves the problem:position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%)...
    程式設計 發佈於2025-07-12
  • 如何在JavaScript對像中動態設置鍵?
    如何在JavaScript對像中動態設置鍵?
    在嘗試為JavaScript對象創建動態鍵時,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正確的方法採用方括號: jsobj ['key''i] ='example'1; 在JavaScript中,數組是一...
    程式設計 發佈於2025-07-12
  • 如何實時捕獲和流媒體以進行聊天機器人命令執行?
    如何實時捕獲和流媒體以進行聊天機器人命令執行?
    在開發能夠執行命令的chatbots的領域中,實時從命令執行實時捕獲Stdout,一個常見的需求是能夠檢索和顯示標準輸出(stdout)在cath cath cant cant cant cant cant cant cant cant interfaces in Chate cant inter...
    程式設計 發佈於2025-07-12
  • Async Void vs. Async Task在ASP.NET中:為什麼Async Void方法有時會拋出異常?
    Async Void vs. Async Task在ASP.NET中:為什麼Async Void方法有時會拋出異常?
    在ASP.NET async void void async void void void void void的設計無需返回asynchroncon而無需返回任務對象。他們在執行過程中增加未償還操作的計數,並在完成後減少。在某些情況下,這種行為可能是有益的,例如未期望或明確預期操作結果的火災和...
    程式設計 發佈於2025-07-12
  • HTML格式標籤
    HTML格式標籤
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    程式設計 發佈於2025-07-12
  • Python讀取CSV文件UnicodeDecodeError終極解決方法
    Python讀取CSV文件UnicodeDecodeError終極解決方法
    在試圖使用已內置的CSV模塊讀取Python中時,CSV文件中的Unicode Decode Decode Decode Decode decode Error讀取,您可能會遇到錯誤的錯誤:無法解碼字節 在位置2-3中:截斷\ uxxxxxxxx逃脫當CSV文件包含特殊字符或Unicode的路徑逃...
    程式設計 發佈於2025-07-12
  • 如何正確使用與PDO參數的查詢一樣?
    如何正確使用與PDO參數的查詢一樣?
    在pdo 中使用類似QUERIES在PDO中的Queries時,您可能會遇到類似疑問中描述的問題:此查詢也可能不會返回結果,即使$ var1和$ var2包含有效的搜索詞。錯誤在於不正確包含%符號。 通過將變量包含在$ params數組中的%符號中,您確保將%字符正確替換到查詢中。沒有此修改,PD...
    程式設計 發佈於2025-07-12
  • `console.log`顯示修改後對象值異常的原因
    `console.log`顯示修改後對象值異常的原因
    foo = [{id:1},{id:2},{id:3},{id:4},{id:id:5},],]; console.log('foo1',foo,foo.length); foo.splice(2,1); console.log('foo2', foo, foo....
    程式設計 發佈於2025-07-12
  • Python元類工作原理及類創建與定制
    Python元類工作原理及類創建與定制
    python中的metaclasses是什麼? Metaclasses負責在Python中創建類對象。就像類創建實例一樣,元類也創建類。他們提供了對類創建過程的控制層,允許自定義類行為和屬性。 在Python中理解類作為對象的概念,類是描述用於創建新實例或對象的藍圖的對象。這意味著類本身是使用...
    程式設計 發佈於2025-07-12
  • 在PHP中如何高效檢測空數組?
    在PHP中如何高效檢測空數組?
    在PHP 中檢查一個空數組可以通過各種方法在PHP中確定一個空數組。如果需要驗證任何數組元素的存在,則PHP的鬆散鍵入允許對數組本身進行直接評估:一種更嚴格的方法涉及使用count()函數: if(count(count($ playerList)=== 0){ //列表為空。 } 對...
    程式設計 發佈於2025-07-12
  • FastAPI自定義404頁面創建指南
    FastAPI自定義404頁面創建指南
    response = await call_next(request) if response.status_code == 404: return RedirectResponse("https://fastapi.tiangolo.com") else: ...
    程式設計 發佈於2025-07-12
  • Python高效去除文本中HTML標籤方法
    Python高效去除文本中HTML標籤方法
    在Python中剝離HTML標籤,以獲取原始的文本表示 僅通過Python的MlStripper 來簡化剝離過程,Python Standard庫提供了一個專門的功能,MLSTREPERE,MLSTREPERIPLE,MLSTREPERE,MLSTREPERIPE,MLSTREPERCE,MLST...
    程式設計 發佈於2025-07-12
  • 解決MySQL插入Emoji時出現的\\"字符串值錯誤\\"異常
    解決MySQL插入Emoji時出現的\\"字符串值錯誤\\"異常
    Resolving Incorrect String Value Exception When Inserting EmojiWhen attempting to insert a string containing emoji characters into a MySQL database us...
    程式設計 發佈於2025-07-12
  • 如何在無序集合中為元組實現通用哈希功能?
    如何在無序集合中為元組實現通用哈希功能?
    在未訂購的集合中的元素要糾正此問題,一種方法是手動為特定元組類型定義哈希函數,例如: template template template 。 struct std :: hash { size_t operator()(std :: tuple const&tuple)const {...
    程式設計 發佈於2025-07-12
  • 如何使用“ JSON”軟件包解析JSON陣列?
    如何使用“ JSON”軟件包解析JSON陣列?
    parsing JSON與JSON軟件包 QUALDALS:考慮以下go代碼:字符串 } func main(){ datajson:=`[“ 1”,“ 2”,“ 3”]`` arr:= jsontype {} 摘要:= = json.unmarshal([] byte(...
    程式設計 發佈於2025-07-12

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3