Node / Express.js:发送邮件后无法设置邮件

时间:2016-09-19 04:40:15

标签: node.js express

我正在开发一个小节点& express.js应用程序。 我在app.get('/lastName/:lastName',(req,res) =>{...});找到了 如果我使用:

res.render('employeeList',{data:employees.lookupByLastName(paramsLastName)});

它始终与res.format({...});冲突 它给了我一个错误:

throw new Error('Can\'t set headers after they are sent.');

当我单独使用它们时,在http://localhost:3000/lastName/Smith我可以得到正确的视图。如果我只使用res.format({...});,我也可以通过以下方式获得正确的api反馈:

curl -X GET -H "Accept:application/xml" "http://localhost:3000/lastName/Smith"

但是,我不能同时使用它们,这与分配要求相冲突。 有人能给我一些线索吗?非常感谢!请参阅以下代码:

'use strict';
const express = require('express');
const _= require('underscore');
const handlebars = require('express-handlebars');
const employees = require('./employeeModule.js');
const bodyParser = require('body-parser');
const app = express();

app.engine('handlebars',
    handlebars({defaultLayout: 'main'}));

app.set('view engine', 'handlebars');

app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

// GET request to the homepage
app.get('/', (req, res) => {
    res.render('home');
});
app.get('/addEmployee',(req,res) => {
    res.render('newEmployee');
});
//..........................Problem here.........................
app.get('/id/:id',(req,res)=>{
    let paramsId = parseInt(req.params.id);
    //res.render('employeeList',{data:employees.lookupById(paramsId)});
    //res.send(employees.lookupById(paramsId));
    res.format({
        'application/json': () => {
            res.json(employees.lookupById(paramsId));
        },
        'application/xml': () => {
            let employeeXml =
                '<?xml version="1.0"?>\n<employees>\n' +
                employees.lookupById(paramsId).map((e)=>{
                    return ' <employee id="' + e.id + '">' +
                        '<firstName>' + e.firstName + '</firstName>'+ '<lastName>' + e.lastName + '</lastName>' + '</employee>';
                }).join('\n') + '\n</employees>\n';
            res.type('application/xml');
            res.send(employeeXml);
        },
        'text/html': () => {
            let employeeHtml = '<ul>\n' +
                employees.lookupById(paramsId).map((e)=>{
                    return ' <li>' + e.id + ' - ' +
                        e.firstName + ' - ' + e.lastName+'</li>';
                }).join('\n') + '\n</ul>\n';

            res.type('text/html');
            res.send(employeeHtml);
        },
        'text/plain': () => {
            let employeeText =
                employees.lookupById(paramsId).map((e)=>{
                    return e.id + ': ' + e.firstName + e.lastName;
                }).join('\n') + '\n';
            res.type('text/plain');
            res.send(employeeText);
        },
        'default': () => {
            res.status(404);
            res.send("<b>404 - Not Found</b>");
        }
    });

});
//..........................Problem here.........................
app.get('/lastName/:lastName',(req,res) =>{
    let paramsLastName  = req.params.lastName;
    res.render('employeeList',{data:employees.lookupByLastName(paramsLastName)});
    res.format({
        'application/json': () => {
            res.json(employees.lookupByLastName(paramsLastName));
        },
        'application/xml': () => {
            let employeeXml =
                '<?xml version="1.0"?>\n<employees>\n' +
                employees.lookupByLastName(paramsLastName).map((e)=>{
                    return ' <employee id="' + e.id + '">' +
                        '<firstName>' + e.firstName + '</firstName>'+ '<lastName>' + e.lastName + '</lastName>' + '</employee>';
                }).join('\n') + '\n</employees>\n';
            res.type('application/xml');
            res.send(employeeXml);
        },
        'text/html': () => {
            let employeeHtml = '<ul>\n' +
                employees.lookupByLastName(paramsLastName).map((e)=>{
                    return ' <li>' + e.id + ' - ' +
                        e.firstName + ' - ' + e.lastName+'</li>';
                }).join('\n') + '\n</ul>\n';

            res.type('text/html');
            res.send(employeeHtml);
        },
        'text/plain': () => {
            let employeeText =
                employees.lookupByLastName(paramsLastName).map((e)=>{
                    return e.id + ': ' + e.firstName + e.lastName;
                }).join('\n') + '\n';
            res.type('text/plain');
            res.send(employeeText);
        },
        'default': () => {
            res.status(404);
            res.send("<b>404 - Not Found</b>");
        }
    });
});

app.post('/data',function (req,res) {
    let bodyData = req.body;
    let bodyDataFirstName  = bodyData.firstName;
    let bodyDataLastName  = bodyData.lastName;
    employees.addEmployee(bodyDataFirstName,bodyDataLastName);
    res.redirect('/lastName/'+bodyDataLastName);
})
app.get('/api/employees',(req,res) =>{
    res.format({
        'application/json': () => {
            res.json(employees.getAllEmployee());
        },
        'application/xml': () => {
            let employeeXml =
                '<?xml version="1.0"?>\n<employees>\n' +
                employees.getAllEmployee().map((e)=>{
                    return ' <employee id="' + e.id + '">' +
                        e.firstName + e.lastName + '</employee>';
                }).join('\n') + '\n</employees>\n';
            res.type('application/xml');
            res.send(employeeXml);
        },
        'text/html': () => {
            let employeeHtml = '<ul>\n' +
                employees.getAllEmployee().map((e)=>{
                    return ' <li>' + e.id + ' - ' +
                        e.firstName + ' - ' + e.lastName+'</li>';
                }).join('\n') + '\n</ul>\n';

            res.type('text/html');
            res.send(employeeHtml);
        },
        'text/plain': () => {
            let employeeText =
                employees.getAllEmployee().map((e)=>{
                    return e.id + ': ' + e.firstName + e.lastName;
                }).join('\n') + '\n';
            res.type('text/plain');
            res.send(employeeText);
        },
        'default': () => {
            res.status(404);
            res.send("<b>404 - Not Found</b>");
        }
    });
});


app.use((req, res) => {
    res.status(404);
    res.render('404');
});


app.listen(3000, () => {
    console.log('http://localhost:3000');
});


/*
 curl -X GET "http://localhost:3000/api/employees"

 curl -X GET -H "Accept:application/json" "http://localhost:3000/api/employees"

 curl -X GET -H "Accept:application/xml" "http://localhost:3000/api/employees"

 curl -X GET -H "Accept:text/html" "http://localhost:3000/api/employees"

 curl -X GET -H "Accept:text/plain"   "http://localhost:3000/api/employees"

 */
/*
 curl -X GET "http://localhost:3000/api/employees"

 curl -X GET -H "Accept:application/json" "http://localhost:3000/lastName/Smith"
 curl -X GET -H "Accept:application/xml" "http://localhost:3000/lastName/Smith"

 curl -X GET -H "Accept:application/json" "http://localhost:3000/id/2"
 curl -X GET -H "Accept:application/xml" "http://localhost:3000/id/2"

 */

2 个答案:

答案 0 :(得分:0)

您正在向同一请求发送两次回复。

当您的代码尝试向同一请求发送两个响应时,会导致您收到错误消息。因此,您必须删除代码中可能发生的所有位置。

GridLayout处理程序中,您首先调用app.get('/lastName/:lastName', ...),然后尝试执行res.render()。但是,您拨打res.send()的方式,该通话已发送对该请求的回复,因此您无法再次拨打res.render()res.send(),因为将尝试向同一请求发送另一个响应,这将触发您看到的错误消息。

如果您尝试仅渲染HTML,然后将该呈现的HTML用作稍后发送的响应的一部分,那么您需要使用其他形式的res.json()来传递它回调,它会使用您稍后可以发送的HTML回拨您。

请参阅res.render()的文档,了解如何使用回调选项获取HTML而不将其作为响应发送,以便以后在发送您要发送的响应时使用它。

一般方案是这样的:

res.render()

答案 1 :(得分:0)

您发送了两次回复。

您的res.render呈现employeeList,然后将其作为回复发送。之后,您尝试发送另一个响应,这是不允许的,并且与请求 - 响应周期不对应。

此外,您还在使用模板引擎呈现您的网页:

let paramsLastName  = req.params.lastName;
res.render('employeeList',{data:employees.lookupByLastName(paramsLastName)});

然后你尝试在这里手动完成:

'text/html': () => {
            let employeeHtml = '<ul>\n' +
                employees.lookupById(paramsId).map((e)=>{
                    return ' <li>' + e.id + ' - ' +
                        e.firstName + ' - ' + e.lastName+'</li>';
                }).join('\n') + '\n</ul>\n';

            res.type('text/html');
            res.send(employeeHtml);
        }

您可以在res.format下的'text/html'内拨打res.render, 使用res.formatapp.render块之外或之外 - 这会呈现html但不会将其作为回复发送。

app.render('index', {data:employees.lookupByLastName(paramsLastName)}, function(err, result) {
    // result is the resulting html from rendering your data.
    // save it to some variable to use later or do something with it here
});