gpt4 book ai didi

javascript - 如何使用 express 和 handlebar 或其他模板引擎在 node.js 中呈现 rest api 调用?

转载 作者:行者123 更新时间:2023-11-29 21:34:20 27 4
gpt4 key购买 nike

用例

使用 Node.js、Express 和 Handlebars 等模板引擎查询 Wordpress 和 CouchDB 等其他 API 并呈现结果。

我已经走了那么远

var https = require('https');

var express = require('express');
var handlebars = require('express-handlebars')
.create({ defaultLayout:'main' });

var app = express();
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
app.set('port', process.env.PORT || 3000);
app.set('ip', process.env.IP);

var options = {
hostname: 'public-api.wordpress.com',
path: '/rest/v1.1/sites/somesite.wordpress.com/posts/16',
method: 'GET'
};

app.get('/test', function(req, res) {
https.request(options, function(restRes) {
console.log('STATUS: ' + restRes.statusCode);
res.render('home', { "title": "Test" }); // This code works.
restRes.on('data', function (jsonResult) {
// res.render('home', { "title": "Test" }); This code (after removing the line above) does not work.
console.log('BODY: ' + jsonResult);
});
}).end();
});

app.listen(app.get('port'), app.get('ip'), function(){
console.log( 'Express started on http://' + app.get('ip') + ": " +
app.get('port') + '; press Ctrl-C to terminate.' );
});

此代码有效并且 jsonResult 在控制台显示正确。移动行 res.render('home', { "title": "Test"});restRes.on('data', function (jsonResult)回调抛出错误。

Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:331:11)
at ServerResponse.header (/home/ubuntu/workspace/node_modules/express/lib/response.js:718:10)
at ServerResponse.send (/home/ubuntu/workspace/node_modules/express/lib/response.js:163:12)
at res.render.done (/home/ubuntu/workspace/node_modules/express/lib/response.js:957:10)
at Immediate._onImmediate (/home/ubuntu/workspace/node_modules/express-handlebars/lib/utils.js:26:13)
at processImmediate [as _immediateCallback] (timers.js:374:17)

我是否监督了一个明显的错误?如何以正确的方式做到这一点?

最佳答案

该错误是不言自明的,即当响应已发送时您无法设置 header 。错误可能是由于以下原因导致的

原因 1

以下操作失败,因为您尝试多次发送响应。

//the following lines send the response 
res.render('home', { "title": "Test" }); // This code works.

restRes.on('data', function (jsonResult) {
//you have already send the response above, hence the error
res.render('home', { "title": "Test" }); This code (after removing the line above) does not work.
console.log('BODY: ' + jsonResult);
});

原因 2

这失败并显示错误,因为 .on('data') 被调用不止一次(取决于响应的大小),这是因为数据以 block 的形式返回,因此,您正尝试多次 res.render

restRes.on('data', function (jsonResult) {
res.render('home', { "title": "Test" });
console.log('BODY: ' + jsonResult);
});

可能的解决方案

您需要使用 .on('data') 接收 block 并在此处构建整个响应,然后使用 .on('end') 来使用完整的响应执行 res.render。内容如下:

var body = '';
//use the chunks to build the whole response into body variable
restRes.on('data', function (chunk) {
body += chunk;
});

//this is called when the request is finished and response is returned
//hence, use the constructed body string to parse it to json and return
restRes.on('end', function () {
console.log('whole response > ' + body);
var jsonObject = JSON.parse(body);
res.render('home', {data:jsonObject});
//in your view use the data that is json object.
});

另一种可能的解决方案与其连接返回到 .on('data') 的 block ,不如将它们放入一个数组中,然后在 .on('end') 中加入数组将构造响应主体然后将其解析为 JSON 然后返回它的元素。示例如下:

var body = [];
restRes.on('data', function(chunk) {
body.push(chunk);
});

restRes.on('end', function() {
//joined the chunks
var result = JSON.parse(data.join(''))
res.render('home', {data: result});
});

关于javascript - 如何使用 express 和 handlebar 或其他模板引擎在 node.js 中呈现 rest api 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35260550/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com