2016-01-25 13 views
1

Ниже приведен файл моего сервера. Я делаю 2 звонка, один пост и один. Он работает отлично. Но дает ошибку: Невозможно установить заголовки после их отправки. Это имеет какое-либо отношение к моему коду на стороне клиента?Экспресс: не удается установить заголовки после их отправки

server.js

var express = require('express') 
var mongoose = require('mongoose') 
var path  = require('path') 
var bodyParser = require("body-parser") 
var cors  = require("cors") 
var app  = express() 
var port  = process.env.PORT || 3000 
var Url  = require("./data/url-schema"); 


//Express request pipeline 
app.use(express.static(path.join(__dirname,"../client"))) 
app.use(bodyParser.json()) 
app.use(cors()); 

/* 
Your server must be ready to handle real URLs. When the app first loads at/it will probably work, but as the user navigates around and then hits refresh at /dashboard your web server will get a request to /dashboard. You will need it to handle that URL and include your JavaScript application in the response. 
*/ 
app.get('*', function (request, response, next){ 
    response.sendFile(path.resolve(__dirname, '../client', 'index.html')) 
    next() 
}) 

app.get('/:code', function(req, res) { 
    console.log("reg", req.params.code) 
    Url.findOne({code:req.params.code}, function(err, data){ 
    console.log("data", data) 
    if(data) 
      res.redirect(302, data.longUrl) 
     else 
      res.end() 
    }) 
}) 

app.post('/addUrl', function (req, res, next) { 
    console.log("on create"); 
    Url.findOne({longUrl:req.body.longUrl}, function(err, data) { 
    if (err) 
     res.send(err); 
    else if(data) { 
     console.log("already exists",data) 
     res.send("http://localhost:3000/"+data.code); 
    } else { 
      var url = new Url({ 
       code : Utility.randomString(6,"abcdefghijklm"), 
       longUrl : req.body.longUrl 
       }); 
      console.log("in last else data created",url) 
       url.save(function (err, data) { 
       console.log(data) 
       if (err) 
        res.send(err); 
       else 
        res.send("http://localhost:3000/"+data.code); 
       }); 
      } 
    }); 
}) 

app.listen(port, function() { 
    console.log('Example app listening on port 3000!') 
}); 

// Connect to our mongo database 
mongoose.connect('mongodb://localhost/shortUrl'); 

Я получаю следующую ошибку

ошибка

_http_outgoing.js:335 
    throw new Error('Can\'t set headers after they are sent.'); 
     ^
Error: Can't set headers after they are sent. 
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11) 
    at ServerResponse.header (/opt/lampp/htdocs/url-shortener/node_modules/express/lib/response.js:718:10) 
    at ServerResponse.location (/opt/lampp/htdocs/url-shortener/node_modules/express/lib/response.js:835:8) 
    at ServerResponse.redirect (/opt/lampp/htdocs/url-shortener/node_modules/express/lib/response.js:874:8) 
    at Query.<anonymous> (/opt/lampp/htdocs/url-shortener/server/server.js:30:8) 
    at /opt/lampp/htdocs/url-shortener/node_modules/mongoose/node_modules/kareem/index.js:177:19 
    at /opt/lampp/htdocs/url-shortener/node_modules/mongoose/node_modules/kareem/index.js:109:16 
    at process._tickCallback (node.js:355:11) 
+0

Невозможно установить заголовки после их отправки, что означает отправку ответа дважды клиенту. Когда это происходит? для получения или публикации? – Subburaj

+1

Не будет маршрута 'app.get ('*', function (request, response, next) { response.sendFile (path.resolve (__ dirname, '../client', 'index.html')) next() }) 'соответствие запросам ALL (get)? так что даже если вы «получите /: code», указанный маршрут будет работать. (следовательно, повторяется ошибка заголовка). –

+0

app.get ('*', function (request, response, next) {response.sendFile (path.resolve (__ dirname, '../client', 'index.html')) next()}) Мне нужно сделайте это, чтобы работающий маршрутизатор работал. Любой другой способ сделать это? –

ответ

0

Наконец нашел решение:

var express = require('express') 
var mongoose = require('mongoose') 
var path  = require('path') 
var bodyParser = require("body-parser") 
var app  = express() 
var port  = process.env.PORT || 3000 
var Url  = require("./data/url-schema") 
var Utility = require("./utility") 

//Express request pipeline 
app.use(express.static(path.join(__dirname,"../client"))) 
app.use(bodyParser.json()) 

/* 
Your server must be ready to handle real URLs. When the app first loads at/it will probably work, but as the user navigates around and then hits refresh at /dashboard your web server will get a request to /dashboard. You will need it to handle that URL and include your JavaScript application in the response. 
*/ 
app.get('/dashboard', function (request, response, next){ 
    response.sendFile(path.resolve(__dirname, '../client', 'index.html')) 
    next() 
}) 
app.get('/about', function (request, response, next){ 
    response.sendFile(path.resolve(__dirname, '../client', 'index.html')) 
    next() 
}) 

app.get('/:code', function(req, res) { 
    Url.findOne({code:req.params.code}, function(err, data){ 
    if(data){ 
      res.redirect(302, data.longUrl) 
    } 
    }) 
}) 

app.post('/addUrl', function (req, res, next) { 
    Url.findOne({longUrl:req.body.longUrl}, function(err, data) { 
    if (err){ 
     res.send(err) 
    } 
    else if(data) { 
     res.send("http://localhost:3000/"+data.code); 
    } else { 
      var newCode = getCode() 
      checkCode(newCode) 
      .then(function(data){ 
       var url = new Url({ 
        code : data, 
        longUrl : req.body.longUrl 
        }); 
        url.save(function (err, data) { 
        if (err) 
         res.send(err); 
        else 
         res.send("http://localhost:3000/"+data.code); 
        }); 
      }) 
      } 
    }); 
}) 

app.listen(port, function() { 
    console.log('Example app listening on port 3000!') 
}); 

// Connect to our mongo database 
mongoose.connect('mongodb://localhost/shortUrl'); 

//Generate a random code 
function getCode() { 
    return Utility.randomString(6,"abcdefghijklmnopqrstuvwxyz") 
} 

//Check if the code is unique 
function checkCode(code) { 
    return new Promise(function (resolve, reject){ 
     Url.findOne({code:code}, function(err, data) { 
      if(err === null){ 
       resolve(code) 
      }else if(data){ 
       saveUrlCode(getCode()) 
      } 
     }) 
    }) 
} 

Мой ранний маршрут, который был:

app.get('*', function (request, response, next){ 
    response.sendFile(path.resolve(__dirname, '../client', 'index.html')) 
    next() 
}) 

Маршрут прибудете получал выполняться дважды на счет выше вызова и app.get (» :/code "). Так что мне пришлось правильно обрабатывать маршруты, которые я выполнил, обратившись к панели управления и о маршрутах отдельно, вместо того, чтобы использовать маршрут «*».

1

От выполнения заказа, в * обработчика маршрута, тело быть назначен к ответу, а затем в /:code, добавляется код ответа 302, где также добавляется заголовок Location, следовательно, ошибка. Любой заголовок должен быть добавлен перед телом в ответ.

Чтобы решить эту проблему, просто измените порядок двух операторов GET.

+0

Итак, как я могу достичь этого? –

+0

Добавлен ответ. – Sam

+0

Это сработало для вас? – Sam

Смежные вопросы