Nodejs 在使用express搭建网站时候的一些问题

Nodejs 在使用express搭建网站时候的一些问题

在我的网站中,比如发布一个话题(不同于显示话题的页面)

  1. 如果我是发布后,等待服务器响应,然后重定向到话题页面的话,这样的实现好不好?
  2. 如果我发布后,直接重定向到话题页面,然后服务器响应后再重新渲染话题页面,这样的实现是否可行?如果这样实现,应该怎么控制服务器响应后的值?
  3. 重定向到话题页面,是重新访问数据库?还是做缓存?做缓存应该怎么做?

求解答了,谢谢

5 回复

当然可以。下面是针对您提出的问题的回答,包括一些示例代码和解释。

1. 发布后等待服务器响应再重定向

这种实现方式是可以的。这种方式确保了数据已经成功保存到数据库之后才进行页面重定向,从而避免了数据丢失的风险。不过需要注意的是,这种方式可能会让用户看到一个短暂的加载状态。

示例代码:

app.post('/topic', (req, res) => {
    const { title, content } = req.body;

    // 假设你有一个数据库模型叫Topic
    const newTopic = new Topic({ title, content });

    newTopic.save((err, topic) => {
        if (err) {
            console.error(err);
            return res.status(500).send('Error saving the topic');
        }
        // 数据保存成功后,重定向到新创建的话题页面
        res.redirect(`/topic/${topic.id}`);
    });
});

2. 发布后立即重定向,然后服务器响应后重新渲染

这种方法也是可行的,但需要小心处理客户端与服务器之间的交互,以确保用户不会因为网络延迟而重复提交表单。你可以通过前端验证或后端生成一个唯一的会话ID来防止重复提交。

示例代码:

// 前端示例(使用fetch API)
document.getElementById('submit-topic').addEventListener('click', async () => {
    const formData = new FormData(document.getElementById('topic-form'));
    const response = await fetch('/topic', {
        method: 'POST',
        body: formData,
        headers: {
            'X-Session-ID': sessionStorage.getItem('session-id')
        }
    });

    if (response.ok) {
        res.redirect('/topic');
    }
});

// 后端示例
app.post('/topic', (req, res) => {
    const { title, content } = req.body;
    const sessionId = req.headers['x-session-id'];

    // 检查会话ID是否有效,避免重复提交
    if (!isValidSession(sessionId)) {
        return res.status(400).send('Invalid session ID');
    }

    const newTopic = new Topic({ title, content });

    newTopic.save((err, topic) => {
        if (err) {
            console.error(err);
            return res.status(500).send('Error saving the topic');
        }
        // 更新会话ID为无效状态
        updateSession(sessionId, false);
        res.redirect(`/topic/${topic.id}`);
    });
});

3. 重定向到话题页面时,如何处理数据库访问和缓存

对于是否需要重新访问数据库或使用缓存,这取决于你的具体需求。如果你的数据不经常变化,可以考虑使用缓存。Express.js 可以与多种缓存中间件结合使用,例如 express-cacheconnect-redis

示例代码(使用 Redis 缓存):

const redis = require('redis');
const client = redis.createClient();

app.get('/topic/:id', (req, res) => {
    const { id } = req.params;

    client.get(`topic:${id}`, (err, cachedData) => {
        if (cachedData) {
            // 如果有缓存数据,直接返回
            return res.send(cachedData);
        }

        // 如果没有缓存数据,从数据库获取并设置缓存
        Topic.findById(id, (err, topic) => {
            if (err) {
                console.error(err);
                return res.status(500).send('Error fetching the topic');
            }

            // 设置缓存
            client.setex(`topic:${id}`, 3600, JSON.stringify(topic));
            res.json(topic);
        });
    });
});

希望这些示例和解释能帮助你解决遇到的问题!


》如果我是发布后,等待服务器响应,然后重定向到话题页面的话,这样的实现好不好?

没别的方法吧。怎么也得等服务器响应,让用户知道发布成功与否。

可以先重定向,然后可能设置某种标识,在这种重定向下,该页面发起ajax,让服务端发送刚插入的记录吗?

一般问题都不大 关键是看你更看重什么, 如果一定不能让发布的东西丢失 那还是等待状态,如果可以容忍,而且你对 响应 要求高的话 直接跳也没什么问题。

对于您提到的问题,我会逐一进行解答,并提供一些示例代码。

  1. 发布后等待服务器响应再重定向

    • 这种做法是合理的。当用户提交表单后,前端发送请求到服务器,服务器处理完数据后返回一个响应(例如,状态码200或201),然后客户端接收到响应并重定向到话题页面。
    • 示例代码:
      app.post('/createTopic', (req, res) => {
        // 处理发布话题的逻辑
        const newTopic = {
          title: req.body.title,
          content: req.body.content
        };
        
        // 存储到数据库
        db.create(newTopic).then((topicId) => {
          // 重定向到话题页面
          res.redirect(`/topic/${topicId}`);
        }).catch((error) => {
          console.error(error);
          res.status(500).send('Internal Server Error');
        });
      });
      
  2. 发布后直接重定向,服务器响应后重新渲染

    • 这种方式也可以实现,但通常不推荐。因为这种方式需要前端在重定向前保存一些信息,以便服务器在响应后能知道当前的状态。
    • 如果采用这种方式,可以在请求时通过URL参数或存储在localStorage中的信息来标识当前的操作状态。
    • 示例代码:
      app.get('/topic/:id', (req, res) => {
        db.find(req.params.id).then(topic => {
          if (req.query.isNew) {
            // 处理新发布的状态
            res.render('topic', { topic, isNew: true });
          } else {
            res.render('topic', { topic });
          }
        });
      });
      
  3. 重定向到话题页面时如何控制缓存

    • 通常情况下,发布的话题页面应避免使用缓存,以确保用户看到的是最新的数据。
    • 如果确实需要缓存,可以考虑使用如Redis等内存数据库来缓存数据,或者使用HTTP缓存控制头(如Cache-Control)。
    • 示例代码:
      app.get('/topic/:id', (req, res) => {
        res.setHeader('Cache-Control', 'no-store');
        db.find(req.params.id).then(topic => {
          res.json(topic);
        });
      });
      

希望这些示例代码和解释能够帮助您更好地理解并解决问题。

回到顶部