使用fetch获取Node.js中的URL脚本内容



我试图使用node fetch从url中提取脚本标记内的内容,然后尝试json解析数据,但我一直得到未定义的返回。

我试图从下面的html中获取变量游戏的内容,然后字符串,然后解析json,但它返回未定义。

页面html:

<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>Document Title</title>
</head>
<body>
<div id="welcome-div">
<p>Welcome to the my website</p>
</div>
<script> 
var game = new Game({
stage: "prod",
servers: {
v32306117: {
id: "v32306117",
name: "name #1",
hostname: "hostname1",
port: 80,
},
v32306125: {
id: "v32306125",
name: "name #2",
hostname: "hostname2",
port: 80,
}
},
userGroup: 0
});
game.init(function() {
game.assetManager.load([{
"name": "/asset/image/map/grass.png",
"url": "/asset/image/map/grass.png"
}]);
game.debug.init();
game.run();
});
</script>
</body>
</html>

提取功能:

const fetch = require("node-fetch");
async function serversFetch() {
try {
const servers = await fetch("https://get-servers.herokuapp.com/");
const data = await servers.text();
const servers_data = data.substring(
data.lastIndexOf("var game =") + 20,
data.lastIndexOf("game.init") - 10
);
return JSON.stringify(servers_data);
} catch (error) {
console.log(error);
}
}
(async () => {
const data = await serversFetch();
console.log('data', data);
const info = JSON.parse(data);
console.log('info', info.servers); // returns undefined
})()

如果我控制台记录info.servers,它会返回未定义的结果,但如果我控制台只记录info,它会记录下面的输出。

info {
stage: "prod",
servers: {
v32306117: {
id: "v32306117",
name: "name #1",
hostname: "hostname1",
port: 80,
},
v32306125: {
id: "v32306125",
name: "name #2",
hostname: "hostname2",
port: 80,
}
},
userGroup: 0
}

您遇到的问题是因为JSON.stringify只适用于JavaScript对象,而servers_data是一个字符串。这导致info稍后成为字符串,这就是console.log(info.servers)记录undefined的原因。当您检查console.log(info)时,由于它记录了对象的字符串值,所以它看起来只能正常工作。您可以通过执行console.log(typeof info)来测试它,您会看到它的类型是string

您希望servers_data是一个有效的JSON字符串,而不是JavaScript对象的字符串(它缺少JSON所需的对象属性名称周围的所有双引号(。第一种选择可能是强制使用,并将这些属性替换为用双引号括起来的属性,即servers:表示"servers:"(包含冒号是为了使其更加独特,但它仍然不是防弹的(。这对像v32306117这样的属性没有帮助,这些属性可能是唯一的,并且无法使用寻找已知属性的强力替换来轻松替换。

下一个选项可能是为字符串创建一个解析器,该解析器可以将字符串解析为JavaScript的抽象语法树(AST(。然后,您可以很容易地将其映射到JSON的AST,然后使用理解JSON的AST的解析器将其修改为字符串。大多数使用AST的解析器可以将字符串解析为AST,并从AST创建字符串。这些解析器通常是使用递归下降解析器编写的。尽管这对程序员来说是一个很好的练习,但您可能会发现一些库可以实现JavaScript和JSON的AST解析器。此外,这对你想要完成的事情来说有点过头了。

我认为最容易实现和维护的最后一个选项是使用JSON5,它是JSON的超集。使用JSON5.parse,您可以按原样解析servers_data,而不必担心JSON格式。这是因为JSON5接受没有双引号的属性,并且对格式(双引号与单引号等(更加宽容

最新更新