我通过在 node.js 项目中获取实际 url 并将该 url 存储在我的 MongoDB 数据库中来生成一个短 url

I am generating a short url by taking an actual url in a node.js project and storing the url in my MongoDB database

提问人:Abhishek 提问时间:11/17/2023 更新时间:11/18/2023 访问量:47

问:

生成短 url 后,当我尝试在浏览器中打开 url 以便将其重定向到原始 url 时,它显示错误。这是浏览器中的错误。我还在下面附上了我的代码:-

This is my urlController.js file

// const shortid = require('shortid');
// const crypto = require('crypto');
const validator = require('validator');
const { validationResult } = require('express-validator');
const Url = require('../models/Url');
const { nanoid } = require('nanoid');

const shortenUrl = async (req, res) => {
  const errors = validationResult(req);

  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }

  const { originalUrl } = req.body;

  if (!originalUrl || !validator.isURL(originalUrl)) {
    return res.status(400).json({ msg: 'Invalid original URL' });
  }

  try {
    const shortCode = nanoid(12); // Generate a short, unique identifier
    const shortUrl = `http://localhost:5000/${shortCode}`;

    const url = await Url.create({
      originalUrl,
      shortUrl,
      user: req.user.id,
    });

    res.json({ shortUrl });
  } catch (error) {
    console.error(error.message);
    res.status(500).send('Server Error');
  }
};

const redirectToOriginalUrl = async (req, res) => {
  const shortUrl = req.params.shortUrl;

  try {
    const url = await Url.findOne({ shortUrl });

    if (!url) {
      console.log('URL not found:', shortUrl);
      return res.status(404).json({ msg: 'URL not found' });
    }

    console.log('Redirecting to:', url.originalUrl);
    res.redirect(url.originalUrl);
  } catch (error) {
    console.error(error.message);
    res.status(500).send('Server Error');
  }
};

const getUserUrls = async (req, res) => {
  try {
    const userUrls = await Url.find({ user: req.user.id });

    res.json(userUrls);
  } catch (error) {
    console.error(error.message);
    res.status(500).send('Server Error');
  }
};

const updateUrl = async (req, res) => {
  const { id } = req.params;
  const { originalUrl } = req.body;

  try {
    let url = await Url.findById(id);

    if (!url) {
      return res.status(404).json({ msg: 'URL not found' });
    }

    url.originalUrl = originalUrl;

    await url.save();

    res.json(url);
  } catch (error) {
    console.error(error.message);
    res.status(500).send('Server Error');
  }
};

const deleteUrl = async (req, res) => {
  const { id } = req.params;

  try {
    let url = await Url.findById(id);

    if (!url) {
      return res.status(404).json({ msg: 'URL not found' });
    }

    await url.deleteOne();

    res.json({ msg: 'URL removed' });
  } catch (error) {
    console.error(error.message);
    res.status(500).send('Server Error');
  }
};

module.exports = {
  shortenUrl,
  redirectToOriginalUrl,
  getUserUrls,
  updateUrl,
  deleteUrl,
};

This code controls all the methods like shortenUrl, redirectToOriginalUrl, etc.
This is my database schema for Url's to be stored.

const mongoose = require('mongoose');

const urlSchema = new mongoose.Schema({
  originalUrl: { type: String, required: true },
  shortUrl: { type: String, required: true, unique: true },
  user: { type: mongoose.Schema.Types.ObjectId, ref: 'User',},
});

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

This is my urlRoutes.js file

const express = require('express');
const router = express.Router();
const urlController = require('../controllers/urlController');
const authenticate = require('../middleware/authMiddleware');

// @route   POST /api/url/shorten
// @desc    Shorten a URL
// @access  Private
router.post('/shorten', authenticate, urlController.shortenUrl);

// @route   GET /api/url/manage
// @desc    Get user's shortened URLs
// @access  Private
router.get('/manage', authenticate, urlController.getUserUrls);

// @route   PUT /api/url/:id
// @desc    Update a shortened URL
// @access  Private
router.put('/:id', authenticate, urlController.updateUrl);

// @route   DELETE /api/url/:id
// @desc    Delete a shortened URL
// @access  Private
router.delete('/:id', authenticate, urlController.deleteUrl);

// @route   GET /:shortUrl
// @desc    Redirect to the original URL
// @access  Public
router.get('/:shortUrl', urlController.redirectToOriginalUrl);

module.exports = router;
This is my main index.js file

const express = require('express');
const connectDB = require('./src/config/db');
require('dotenv').config();

const app = express();

// Connect to MongoDB
connectDB();

// Middleware
app.use(express.json({ extended: false }));

// Routes
app.use('/api/auth', require('./src/routes/authRoutes'));
app.use('/api/url', require('./src/routes/urlRoutes'));

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

我正在做的是,我正在通过Postman通过HTTP POST请求缩短URL,并且在Postman中以JSON的形式获得缩短的URL。这是邮递员的图片现在,在生成短 url 后,我正在尝试发出 GET 请求,以便它显示原始 url,但它抛出错误。这是 Postman 中的错误

我试图实现的是,当生成短 url 时,短 url 可以正常工作,我可以在浏览器中打开短 url 后重定向到原始 url,并且当我通过短 url 在 postman 中发出 GET 请求时,它会将我重定向到原始 url。

还有一件事,我的网址完美地存储在我的MongoDB数据库中。

如果需要更多信息,我可以提供,但我根本无法解决此问题。任何帮助将不胜感激。

Node.js MongoDB Express

评论

0赞 tkausl 11/17/2023
您的所有路由都有前缀,这包括重定向 url。./src/routes/urlRoutes'/api/url'
0赞 Abhishek 11/17/2023
对于重定向到原始 Url,路由为“localhost:5000/<缩短的 Url>”。在对上述路由发出 GET 请求后,它应该将我重定向到原始 URL。
1赞 tkausl 11/17/2023
For the redirect to original url, the route is 'localhost:5000/<the shortened url>'.不,不是。尝试'localhost:5000/api/url/<the shortened url>'
0赞 Abhishek 11/17/2023
我试过了,但现在它给了我“如果找不到 url 语句”,您可以检查我发布的代码 -> urlController 文件中的 redirectToOriginalUrl 方法.js。在邮递员中,它给了我 { “msg” : “URL not found” } 作为 JSON。
0赞 Abhishek 11/17/2023
那么你认为错误是什么,我的重定向到原始 url 路由是否配置不正确?

答:

0赞 jQueeny 11/18/2023 #1

您安装路由器的方式意味着这里:

router.get('/:shortUrl

这意味着该路由实际上是因为您将路由器安装在:/api/url/:shortUrl

app.use('/api/url', urlController.redirectToOriginalUrl);

更改此设置:

const shortUrl = `http://localhost:5000/${shortCode}`;

对此:

const shortUrl = `http://localhost:5000/api/url/${shortCode}`;

然后,当您寻找时,您必须像这样操作:shorturl

const url = await Url.findOne({ shortUrl: `http://localhost:5000/api/url/${shortUrl}` });

接下来,您可能希望将处理 get 请求的路由移动到不同的挂载点,但这取决于您。目前,您必须处理对函数的 get 请求的唯一路由是 。shortUrlredirectToOriginalUrl/api/url/:shortUrl