我正在尝试从jokeAPI解析数据以生成随机笑话。我使用了response.on()和JSON.parse()函数,并且已经获得了200 statusCode,所以我知道我的代码可以正常工作,但是我总是遇到错误。
这是我的代码:
const express = require("express");
const https = require("https");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.urlencoded({
extended: true
}));
app.get("/", function(req, res) {
const url = "https://sv443.net/jokeapi/v2/joke/Any?blacklistFlags=nsfw"
https.get(url, function(response) {
console.log(response.statusCode);
response.on("data", function(data){
const jokeData = JSON.parse(data);
console.log(jokeData);
});
});
res.sendFile(__dirname + "/index.html");
});
app.listen(3000, function() {
console.log("Server is running on port 3000.");
});
这是我在Hyper中得到的回复:
Server is running on port 3000.
200
undefined:6
"delivery": "T
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at IncomingMessage.<anonymous> (/Users/aimee/Documents/JokeProject/app.js:16:29)
at IncomingMessage.emit (events.js:315:20)
at IncomingMessage.Readable.read (_stream_readable.js:506:10)
at flow (_stream_readable.js:1006:34)
at resume_ (_stream_readable.js:987:3)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
[nodemon] app crashed - waiting for file changes before starting...
我已经研究了错误,尝试修复我的代码,查看了similar questions like mine on Stack Overflow和other sites like teamtreehouse.com和stechies.com,尝试了他们的建议以及其他无数雪茄的建议。有谁知道我该如何解决?
!!-更新-!!
按照ReadableStream的建议阅读its data event和T.J. Crowder的文档后,我更新了dwosk编写的代码:
app.get("/", function(req, res) {
const url = "https://sv443.net/jokeapi/v2/joke/Any?blacklistFlags=nsfw"
https.get(url, function(response) {
console.log(response.statusCode);
let body = '';
response.on("data", function(data){
body += data;
});
response.on("end", function() {
var resp = JSON.parse(body);
console.log(resp);
})
});
res.sendFile(__dirname + "/index.html");
});
现在我的代码可以工作了,我的数据也被解析了。
Server is running on port 3000.
200
{
error: false,
category: 'Programming',
type: 'single',
joke: 'If Bill Gates had a dime for every time Windows crashed ... Oh wait, he does.',
flags: {
nsfw: false,
religious: false,
political: false,
racist: false,
sexist: false
},
id: 22,
lang: 'en'
}
它有助于了解ReadableStream及其数据事件,在得知数据回调不是整个主体之后,我设法通过将新数据附加到字符串中来获取完整的JSON文本,从而使我能够解析数据。
答案 0 :(得分:2)
data
事件为您提供了大块的数据,而不是全部数据。请参见ReadableStream及其data
event的文档。
直到end
event,您都不知道数据是完整的。以下是end
事件文档中的示例,显示了其工作原理:
const readable = getReadableStreamSomehow(); readable.on('data', (chunk) => { console.log(`Received ${chunk.length} bytes of data.`); }); readable.on('end', () => { console.log('There will be no more data.'); });
或者来自http.get
documentation(https.get
文档链接到的该示例):
let rawData = ''; res.on('data', (chunk) => { rawData += chunk; }); res.on('end', () => { try { const parsedData = JSON.parse(rawData); console.log(parsedData); } catch (e) { console.error(e.message); } });
请注意,假定已提供了编码,因此块是字符串,而不是Buffer
实例。
答案 1 :(得分:0)
每次输入一些数据都会触发data
事件。
这在您流式传输大量数据时非常有用,因为您可以在传入数据时逐块处理它。
您无法逐步解析JSON(至少不是使用标准JSON解析器)。您需要完整 JSON文本,否则将发现一个异常。
每次触发data
时,将新数据追加到字符串中。
在end
事件触发时,然后将该字符串解析为JSON。
您可能想使用一个库,该库负责为您收集所有数据,甚至可能有一个内置处理JSON的工具。例如node-fetch
或axios
。
答案 2 :(得分:0)
传递给data
回调的参数不是整个主体。请尝试以下操作:
const url = "https://sv443.net/jokeapi/v2/joke/Any?blacklistFlags=nsfw"
https.get(url, function(response) {
console.log(response.statusCode);
let body = '';
response.on("data", function(data){
body += data;
});
response.on("end", function() {
var res = JSON.parse(body);
console.log(res); // prints your api response
});
});