【问题标题】:Update the todo list without refreshing the page in express nodejs app在 express nodejs 应用程序中更新待办事项列表而不刷新页面
【发布时间】:2015-08-19 06:01:33
【问题描述】:

我是 express nodejs 应用程序的新手。我想做一个待办事项清单。到目前为止,这就是它的样子。我的问题是当我添加待办事项时,需要一些时间来显示更改,因为它会重新加载页面。如何在不重新加载页面的情况下实时查看更改。 提前致谢。

tasks.jade

 h1= title

  .list
    .item.add-task
      div.action
        form(action='/tasks', method='post', id='12345')
          input(type='hidden', value='true', name='all_done')
          input(type='hidden', value=locals._csrf, name='_csrf')
          input(type='submit', class='btn btn-success btn-xs', value='all done')
      form(action='/tasks', method='post')
        input(type='hidden', value=locals._csrf, name='_csrf')
        div.name
          input(type='text', name='name', placeholder='Add a new task')
        div.delete
          input.btn.btn-primary.btn-sm(type="submit", value='add')
    if (tasks.length === 0)
      | No tasks.
    each task, index in tasks
      .item
        div.action
          form(action='/tasks/#{task._id}', method='post')
            input(type='hidden', value=task._id.toString(), name='id')
            input(type='hidden', value='true', name='completed')
            input(type='hidden', value=locals._csrf, name='_csrf')
            input(type='submit', class='btn btn-success btn-xs task-done', value='done')
        div.num
          span=index+1
            |. 
        div.name
          span.name=task.name + ' (Created at: ' + moment(task.createTime).format("YYYY/MM/DD") + ')'
          //- no support for DELETE method in forms
          //- http://amundsen.com/examples/put-delete-forms/
          //- so do XHR request instead from public/javascripts/main.js
        div.delete
          a(class='btn btn-danger btn-xs task-delete', data-task-id=task._id.toString(), data-csrf=locals._csrf) delete

app.js

app.get('/', routes.index);
app.get('/tasks', tasks.list);
app.post('/tasks', tasks.markAllCompleted)
app.post('/tasks', tasks.add);
app.post('/tasks/:task_id', tasks.markCompleted);
app.delete('/tasks/:task_id', tasks.del);
app.get('/tasks/completed', tasks.completed);

tasks.js

exports.add = function(req, res, next){
  if (!req.body || !req.body.name) return next(new Error('No data provided.'));
  req.db.tasks.save({
    name: req.body.name,
    createTime: new Date(),
    completed: false
  }, function(error, task){
    if (error) return next(error);
    if (!task) return next(new Error('Failed to save.'));
    console.info('Added %s with id=%s', task.name, task._id);
    res.redirect('/tasks');
  })
};

【问题讨论】:

  • 你肯定会喜欢 AJAX 请求。

标签: javascript node.js asynchronous express mean-stack


【解决方案1】:

ExpressJS 是一个服务器端框架。这意味着当浏览器向视图发出请求时,它会提供视图。为了防止浏览器在与页面交互时刷新整个页面,您需要查看客户端框架。

我强烈建议您查看AngularJS,但这对于初学者来说可能是一个令人生畏的框架。如果你还没有,我肯定会先学习JQuery。许多其他框架要么直接构建在 JQuery 之上,要么模仿 JQuery 使用的一些模式。我会先专注于 JQuery,然后毕业到更高级别的框架,如 AngularJS 或类似的东西。

这是一个使用 JQuery 劫持表单提交的示例:

<script type="text/javascript">
  $('#myForm').on('submit', function (event) {
    event.preventDefault(); // Stop the form from causing a page refresh.
    var data = {
      username: $('#username').val(),
      password: $('#password').val()
    };
    $.ajax({
      url: 'http://localhost/my/url',
      data: data,
      method: 'POST'
    }).then(function (response) {
      // Do stuff with the response, like add it to the page dynamically.
      $('body').append(response);
    }).catch(function (err) {
      console.error(err);
    });
  });
</script>

如果您将该脚本标记放在页面底部,就在关闭&lt;/body&gt; 标记之前,它将劫持一个ID 为myForm 的表单并为submit 事件附加一个事件处理程序。提交表单时,事件处理程序将首先触发。处理程序event.preventDefault() 的第一行告诉浏览器不要执行默认提交行为并刷新页面。然后,我们创建一个data 对象来存储我们感兴趣的表单字段的值。在这个示例中,我使用ID 为“用户名”的文本输入和ID 为“密码”的密码输入。注意你传递给$()的字符串看起来很像一个CSS选择器,这就是想法:)

一旦我们有了想要发布到服务器的数据,我们就会用数据发出AJAX 请求,然后我们处理响应,或者在发生错误时捕获任何错误。此 AJAX 请求在不刷新页面的情况下发生 :)

此脚本必须位于页面底部的原因是需要在运行之前加载元素。 JQuery 可以确保在运行脚本之前准备好整个文档。

$(document).on('ready', function (event) {
  // This code won't run until the whole page is ready.
});

如果您将代码放在该事件处理程序中,那么您可以将脚本标记放在页面上的任何位置,甚至在&lt;head&gt; 中。 JQuery 为该事件处理程序提供了一个快捷方式,因为它被大量使用。

$(function (event) {
  // This is sugar for $(document).on('ready', function () { ... });
});

【讨论】:

  • 这对我有用。为了确认,我想我应该将一些带有“数据”的密钥发送到“localhost/my/url”,以便在服务器端我只响应它与我的密钥匹配以防止欺诈呼叫,是吗? :)
  • 我不确定你的意思。 AJAX 请求(从服务器的角度来看)与传统的表单提交并没有什么不同。唯一的区别是浏览器不会向服务器发出完整的请求,而是在后台发出 AJAX 请求。
  • 谢谢。我的意思是,我认为有些人也可以使用我们的提交 url 将数据保存到数据库中,而无需访问网站,如果我理解正确的话。我们必须避免它还是自动处理它?
  • 网络安全是一个完全不同的话题 XD。简短的回答是“不,AJAX 不会引入任何您使用的经典表单提交样式尚未出现的安全漏洞。”长答案是“是的,任何人都可以向您的端点发出请求,而您将想了解有关 web authentication 的所有信息。”
  • 感谢您提供出色的答案和资源。
【解决方案2】:

您的服务器应该返回 JSON 而不是呈现的 HTML。在前端,您应该使用 JavaScript(例如 jQuery 和方法 $.getJSON())来查询您的服务器以获取更新的任务列表。 jQuery 将使用 AJAX 从您的服务器发送和接收数据,而无需刷新您的页面。网上有很多关于如何使用 Node.js 制作 REST API 的好教程。

【讨论】:

  • 在这种应用程序中使用 web-sockets over ajax 是个好主意吗?
  • @AlexStack 你绝对可以使用 websockets 而不是经典的 AJAX 请求,但作为初学者,我强烈建议在深入研究 websockets 之前学习所有关于 AJAX/XHR 的知识。
  • 谢谢@IvanJ。有道理。据我所知,如果我们使用 websockets 这样做会提高性能吗?
  • 不是,不是。如果您正在实时执行某些操作,例如聊天应用程序,那么这很重要。
  • @Ivan 有道理。谢谢你的回答。
猜你喜欢
  • 2019-01-12
  • 1970-01-01
  • 1970-01-01
  • 2020-12-23
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多