因此,第一次渲染成功app.get("/", function(request, response)
,但是当我处理app.post("/search", urlencodedParser, function(request, response)
我收到错误:
c:\ weather \ views \ main.hbs:发送后不能设置标题。
我看过The function
res.render()should only be called once per request.
,但我不明白 - 如果可以的话,如何使用views(Handlebars)
更改数据?用新数据再次调用渲染?
var express = require("express");
var fs = require("fs");
var bodyParser = require("body-parser");
var hbs = require("hbs");
// create object
var app = express();
//urlEncoded
var urlencodedParser = bodyParser.urlencoded({
extended: false
});
//read city.json
var content = fs.readFileSync("./city.list.json", "utf8");
var cities = JSON.parse(content);
//set view Handlebars
app.set("view engine", "hbs");
//register Helper - ResultBlock
hbs.registerHelper("ResultBlock", function(array) {
var res = "";
if (array[0] == "false") {
res = '<div class="alert alert-warning alert-dismissible fade show"><button type="button" class="close" data-dismiss="alert">×</button><strong>Not Found!</strong> The ' + array[1] + ' is not correct.</div>';
} else if (array[0] == "true") {
res = 'Succsesful!!!';
}
return new hbs.SafeString(res);
})
app.get("/", function(request, response) {
//response.sendfile('index.html');
response.render("main.hbs", {
city_value: "Zaporozhye",
data: []
})
});
app.post("/search", urlencodedParser, function(request, response) {
var city = request.body.city;
var idCity = -1;
for (let i = 0; i < cities.length; i++) {
if (cities[i].name == city) {
idCity = cities[i].id;
break;
}
}
if (idCity != -1) {
response.render("main.hbs", {
city_value: city,
data: ["true", city]
})
} else {
response.render("main.hbs", {
city_value: city,
data: ["false", city]
})
}
response.end();
});
app.listen(3000);
&#13;
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="app.js" type=""></script>
<link rel="stylesheet" href="style.css">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid" style="background-color:black; color:darkorange;">
<div class="row">
<div class="col">
<h1>Weather</h1>
</div>
<div class="col-*-*">
<form action="/search" method="post">
<div class="row">
<div class="col">
<input type="text" class="form-control" name="city" value="{{city_value}}" />
</div>
<div class="col">
<button type="submit" class="btn btn-primary">Search</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div id="result_block" class="container">
{{ResultBlock data}}
</div>
</body>
</html>
&#13;
答案 0 :(得分:2)
response.render
是一个异步函数。因此,渲染是在当前执行上下文完成之后完成的。
在代码的最后,您调用response.end()
并因此在渲染开始之前完成响应。
完成响应后,异步呈现函数将启动并尝试设置标题,但这是不可能的,因为响应已经完成,这就是您收到该错误的原因。
删除response.end()
,一切都应该正常。
答案 1 :(得分:0)
你应该删除response.end()行,因为你使用了response.render
答案 2 :(得分:0)
函数response.end()用于发送响应的标头并结束响应过程。
另一方面,函数response.render()呈现视图,并且还发送标题并结束响应。
在同一个响应对象上调用两个将尝试为同一个请求发送两次头,这是不可能的,因为每个请求只能有一个响应。
response.end()
应该解决问题。
app.post("/search", urlencodedParser, function(request, response) {
var city = request.body.city;
var idCity = -1;
for (let i = 0; i < cities.length; i++) {
if (cities[i].name == city) {
idCity = cities[i].id;
break;
}
}
if (idCity != -1) {
response.render("main.hbs", {
city_value: city,
data: ["true", city]
})
} else {
response.render("main.hbs", {
city_value: city,
data: ["false", city]
})
}
});