【问题标题】:express can't get after posting快递寄出后收不到
【发布时间】:2016-10-28 15:04:58
【问题描述】:

我正在使用 Vue.js、Express 和 MongoDB 编写一个 Web 应用程序。 Express 服务器有两个 Vue 客户端将使用的路由: POST: /post;获取:/发布;第一个是发帖,一个是获取帖子;

当我发布帖子时(客户端请求 POST /post);帖子发布成功,然后客户端去第一页获取帖子(client beg GET /post),但是服务器报错:'Can't set headers after they are sent.',我要重启服务器,然后一切正常,刚才发布的帖子正常显示了。

我尝试了很多,但我无法解决,我需要你的帮助。

express 的 /post 路由器:

var express = require('express');
var router = express.Router();
var Post = require('../models/post');
var moment = require('moment');
var jwt = require("jwt-simple");

router.get('/',function(req,res,next){
    Post.get(function(err,posts){
        if(err){
           res.status(404);
           res.end();
        }
    res.status(200);
    res.json({
        posts:posts
    });
  });
});
  router.post('/',function(req,res,next){
      var token = req.body.access_token;
      if(token){
      try{
        var decoded = jwt.decode(token,req.app.get('jwtTokenSecret'));
        if(decoded.exp < Date.now()){
            console.log("haha")
            res.end('token expired',401);
        }
        //console.log(decoded)
         var newPost = new Post({
            name:decoded.iss,
            title:req.body.title,
            content:req.body.content
        });
        console.log(newPost);
        newPost.save(function(err,post){
            if(err){
                console.log("publish failed");
                res.status(500);
                res.send({error:1});
            }
            console.log('publish done');
        });
        res.status(200);
        res.send({});
    } catch(err){
        res.status(401);
        res.send('no token');
    }
 }
});
module.exports = router;

【问题讨论】:

  • 似乎是一个逻辑缺陷,无论newPost.save() 函数中发生什么,您都在执行res.send({});,但如果失败,您将尝试再次设置status 标头,但你不能,因为标头已经发送并且你已经开始在异步 save() 函数之外输出。
  • 我只是将其修改为 res.end() ,但同样的错误
  • newPost.save() 运行良好,GET '/post' 时报错
  • 好吧,GET 路由做同样的事情,如果出错,它会尝试设置 status 头两次。
  • 现在我发现错误来自 Post.get();但我不知道为什么,因为它在我重新启动服务器时工作。能否请您看一下我在github上的代码,地址是:github.com/laoqiren/vue-express-forum 非常感谢

标签: javascript node.js express vue.js


【解决方案1】:

改变你的路线来做

router.get('/',function(req,res,next){
    Post.get(function(err,posts){
        if(err){
           res.status(404);
           res.end();
        } else {
           res.status(200);
           res.json({
                posts:posts
           });
        }
    });
});

router.post('/', function(req, res, next) {
    var token = req.body.access_token;
    if (token) {
        var decoded = jwt.decode(token, req.app.get('jwtTokenSecret'));
        if (decoded.exp < Date.now()) {
            console.log("haha")
            res.end('token expired', 401);
        } else {
            var newPost = new Post({
                name: decoded.iss,
                title: req.body.title,
                content: req.body.content
            });

            newPost.save(function(err, post) {
                if (err) {
                    console.log("publish failed");
                    res.status(500);
                    res.send({error: 1});
                } else {
                    res.status(200);
                    res.send({});
                }
            });
        }
    } else {
        res.status(401);
        res.send('no token');
    }
});
module.exports = router;

或者在error子句中return,否则会尝试设置status头两次,最后一次输出已经生成。

【讨论】:

  • 现在我发现错误来自 Post.get();但我不知道为什么,因为它在我重新启动服务器时工作。能否请您看一下我在github上的代码,地址是:github.com/laoqiren/vue-express-forum 非常感谢
  • 在帖子发布成功后服务器尝试打开mongodb时似乎出现错误,但GET'/post'没有捕获它
  • 您的/post 路由有同样的问题,多个send 之后尝试设置标题。我会发布两条固定路线。
  • 我已经像上面的代码一样修改了它们,但是 Post.get() 运行错误。去 GET '/post' 时 mongodb 打不开
  • 但是当我重新启动服务器时,GET 'post' 运行良好
猜你喜欢
  • 2018-07-01
  • 2022-01-11
  • 2016-05-11
  • 2013-04-02
  • 2016-06-24
  • 1970-01-01
  • 2014-12-17
  • 1970-01-01
  • 2018-08-20
相关资源
最近更新 更多