无法访问脚本内 EJS 模板中的 JSON
Not able to access JSON in EJS template inside script
我正在尝试构建一个基于从节点传递到客户端的 JSON 呈现动态图表的网络应用程序。
但是我无法访问 <script>
中的 json 变量。我已经使用
测试了 JSON 对象
console.log(<%= data %>)
它出现在那里。
我的节点代码如下:
let ltlasJSON = JSON.parse(ltlasData);
app.get("/results", function(req, res){
var query = req.query.postalCode;
var url = "http://api.postcodes.io/postcodes/" + query;
request(url, function(error, response, body){
if(!error && response.statusCode == 200){
var data = JSON.parse(body);
var adminDistrict = data["result"]["codes"]["admin_district"];
var filtered = ltlasJSON.filter(a=>a.areaCode==adminDistrict);
res.render("results", {data: filtered});
}
}
);
});
results.ejs:
<<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Engliand Covid-19 </title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<h1>Results Page</h1>
<script>
var specimenDate = <%= data.areaCode %>
var cases = <%= data.dailyLabConfirmedCases %>
var data1 = [
{
x: specimenDate,
y: cases,
type: 'bar'
}
];
Plotly.newPlot('myDiv', data);
</script>
</body>
</html>
我是 node 和 ejs 的新手。最终目标是在 plotly 对象的 x 和 y 变量中传递 JSON(两个字段)的数组。
我在这里看到两个问题:
1) 您将数据错误地传递到前端 javascript。 <%=
总是错误的,因为它编码了 HTML 个实体,但我们在 JS 脚本标签中而不是在常规 HTML 中。相反,您想使用 JSON.stringify
将其作为 JSON 传递,并使用 <%-
来防止 HTML-encoding:
var specimenDate = <%- JSON.stringify(data.areaCode) %>
这仍然有两个问题:首先,JSON.stringify(undefined)
将产生 undefined
(而不是字符串),它在 <%-
之后变成空输出,因此您将得到一个语法如果值未定义则出错。其次,包含 </script>
的字符串将逃脱脚本块并造成严重破坏。我建议使用 devalue
而不是 JSON.stringify
.
2) 您正在访问 data.areaCode
,但我看到 data
实际上来自 filtered
,而 filtered
是 Array.prototype.filter
的结果调用,其中 returns 所有匹配元素的数组。然而,您正在访问 areaCode
属性 就好像 data
直接是匹配元素之一,而不是所有匹配元素的数组。
如果你打算在那里有一个数组,你必须遍历它的条目,或者直接访问一个条目,例如 data[0].areaCode
(但你还必须确保 data[0]
是始终存在)。
如果这不是故意的,那么你只是使用了错误的数组方法。您可以使用 Array.prototype.find
到 return 第一个匹配项或 undefined
否则。
示例:
const db = [
{ areaCode: 1, text: 'A' },
{ areaCode: 2, text: 'B' },
{ areaCode: 2, text: 'C' }
]
console.log(db.filter(el => el.areaCode === 1)) // [{ areaCode: 1, text: 'A' }]
console.log(db.filter(el => el.areaCode === 2)) // [{ areaCode: 2, text: 'B' },
// { areaCode: 2, text: 'C' }]
console.log(db.filter(el => el.areaCode === 3)) // []
console.log(db.find(el => el.areaCode === 1)) // { areaCode: 1, text: 'A' }
console.log(db.find(el => el.areaCode === 2)) // { areaCode: 2, text: 'B' }
console.log(db.find(el => el.areaCode === 3)) // undefined
我正在尝试构建一个基于从节点传递到客户端的 JSON 呈现动态图表的网络应用程序。
但是我无法访问 <script>
中的 json 变量。我已经使用
console.log(<%= data %>)
它出现在那里。
我的节点代码如下:
let ltlasJSON = JSON.parse(ltlasData);
app.get("/results", function(req, res){
var query = req.query.postalCode;
var url = "http://api.postcodes.io/postcodes/" + query;
request(url, function(error, response, body){
if(!error && response.statusCode == 200){
var data = JSON.parse(body);
var adminDistrict = data["result"]["codes"]["admin_district"];
var filtered = ltlasJSON.filter(a=>a.areaCode==adminDistrict);
res.render("results", {data: filtered});
}
}
);
});
results.ejs:
<<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Engliand Covid-19 </title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<h1>Results Page</h1>
<script>
var specimenDate = <%= data.areaCode %>
var cases = <%= data.dailyLabConfirmedCases %>
var data1 = [
{
x: specimenDate,
y: cases,
type: 'bar'
}
];
Plotly.newPlot('myDiv', data);
</script>
</body>
</html>
我是 node 和 ejs 的新手。最终目标是在 plotly 对象的 x 和 y 变量中传递 JSON(两个字段)的数组。
我在这里看到两个问题:
1) 您将数据错误地传递到前端 javascript。 <%=
总是错误的,因为它编码了 HTML 个实体,但我们在 JS 脚本标签中而不是在常规 HTML 中。相反,您想使用 JSON.stringify
将其作为 JSON 传递,并使用 <%-
来防止 HTML-encoding:
var specimenDate = <%- JSON.stringify(data.areaCode) %>
这仍然有两个问题:首先,JSON.stringify(undefined)
将产生 undefined
(而不是字符串),它在 <%-
之后变成空输出,因此您将得到一个语法如果值未定义则出错。其次,包含 </script>
的字符串将逃脱脚本块并造成严重破坏。我建议使用 devalue
而不是 JSON.stringify
.
2) 您正在访问 data.areaCode
,但我看到 data
实际上来自 filtered
,而 filtered
是 Array.prototype.filter
的结果调用,其中 returns 所有匹配元素的数组。然而,您正在访问 areaCode
属性 就好像 data
直接是匹配元素之一,而不是所有匹配元素的数组。
如果你打算在那里有一个数组,你必须遍历它的条目,或者直接访问一个条目,例如 data[0].areaCode
(但你还必须确保 data[0]
是始终存在)。
如果这不是故意的,那么你只是使用了错误的数组方法。您可以使用 Array.prototype.find
到 return 第一个匹配项或 undefined
否则。
示例:
const db = [
{ areaCode: 1, text: 'A' },
{ areaCode: 2, text: 'B' },
{ areaCode: 2, text: 'C' }
]
console.log(db.filter(el => el.areaCode === 1)) // [{ areaCode: 1, text: 'A' }]
console.log(db.filter(el => el.areaCode === 2)) // [{ areaCode: 2, text: 'B' },
// { areaCode: 2, text: 'C' }]
console.log(db.filter(el => el.areaCode === 3)) // []
console.log(db.find(el => el.areaCode === 1)) // { areaCode: 1, text: 'A' }
console.log(db.find(el => el.areaCode === 2)) // { areaCode: 2, text: 'B' }
console.log(db.find(el => el.areaCode === 3)) // undefined