【发布时间】:2019-04-24 14:51:56
【问题描述】:
当我从我正在构建的 Javascript 应用程序中保存 JSON 格式的文件时(在 Node v6.11.0 上使用 Express 在我的本地机器上运行它,端口 3000),我有时会收到错误:
SyntaxError: Unexpected token l in JSON at position 65032,其中“token”是我认为是JSON被截断之前的最后一个字符的任何字符,并且“位置”似乎总是“650xx”,有时为低至 65029,有时高达 65036。
当我删除文件中的某些内容以使其长度可能小于此长度时,它保存得很好,这让我相信我正在达到某种默认长度限制,但从哪里开始,我不能说。我在这个问题上所做的搜索似乎表明 JSON 长度的限制至少在 MB 范围内,我保存的最大文件是 104kB。同时,我在 Node.js 中发现的限制(如果有的话)至少也在 MB 范围内。
我正在保存的 JSON 是由以下内容生成的:
var saveCognitionFile = function( filename, content, url ){
// Attach the camera state so that we can reinstate it at file load.
attachCameraStateToCognition();
var httpRequest = new XMLHttpRequest();
var body = {};
var jBody;
if ( url ){
body.fullpath = url + '/' + filename; // filename includes ext
}
else if ( !url || url === "" ){
body.fullpath = filename;
}
body.data = content;
jBody = JSON.stringify( body, circRefFilter );
// Send the request
httpRequest.open( "POST", '/saveCognition', true );
httpRequest.setRequestHeader( "Content-Type", "application/json;charset=UTF-8" );
httpRequest.send( jBody );
debug.master && debug.saveCognition && console.log( httpRequest );
updateUserFilesList();
};
其中circRefFilter 是一个字符串数组,用于过滤要发送的 JSON 中包含哪些键/值对。
然后在服务器端,我这样做:
router.post('/saveCognition', function( req, res, next ) { console.log( 'Accessing the Save Cognition route...' );
next();
},
function( req, res, next ) {
req.on( 'error', function(){
console.log( 'error!' );
});
req.on( 'data', function( data ) {
console.log( 'data at router.post: ', data );
var jParsed = JSON.parse( data );
console.log( 'data parsed: ', jParsed );
jsonMethods.saveCognitionJson( jParsed.fullpath, jParsed.data );
});
req.on( 'end', function(){
console.log( req );
});
next();
},
function( req, res ) {
res.send('save the current cognition file!');
}
);
考虑到我可能会遇到某种 JSON 字符串长度限制,我确实理解分块发送文件可能是有意义的,但我不确定这是否是解决方案,或者如何解决这样做。
帮助表示赞赏。
谢谢!
针对帕特里克·埃文斯 (Patrick Evans) 的以下第一次报价进行更新。
可能到达那里,但是...我现在收到错误
TypeError: Cannot read property 'length' of undefined
at Function.Buffer.concat (buffer.js:304:24)
at IncomingMessage.<anonymous> (C:\Users\Mark\documents\permiebot\research\experiments\three-js\lucidnodes\routes.js:52:24)
at emitNone (events.js:86:13)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickCallback (internal/process/next_tick.js:104:9)
这是更新的服务器端代码:
router.post('/saveCognition', function( req, res, next ) { console.log( 'Accessing the Save Cognition route...' );
next();
},
function( req, res, next ) {
let reqData = [];
let buffer;
req.on( 'error', function(){
console.log( 'error!' );
});
req.on( 'data', function( data, chunk ) {
reqData.push( chunk );
console.log( 'data at router.post: ', data );
});
req.on( 'end', function(){
buffer = Buffer.concat( reqData ).toString();
var jParsed = JSON.parse( /* data */ buffer );
console.log( 'data parsed: ', jParsed );
jsonMethods.saveCognitionJson( jParsed.fullpath, jParsed.data );
console.log( req );
});
next();
},
function( req, res ) {
res.send('save the current cognition file!');
}
);
显然我没有正确连接。删除 .toString() 无济于事。谢谢。
嗯,第二个错误的 UPDATE 原来是一个简单的修复。请看下面我的回答。感谢 @PatrickEvans 在 cmets 中提供的帮助。
【问题讨论】:
-
.on('data'...被多次调用(即您的数据以块的形式出现),继续连接data然后在.on('end'中进行解析 -
@PatrickEvans ...几乎就在那里,但是...请参阅上面的编辑。我显然没有以某种方式正确连接。
-
@PatrickEvans 从不介意最后的评论。我刚刚开始工作。第二个问题是我试图将“块”作为第二个参数推送,它是空的。感谢您的帮助。
标签: javascript node.js json stringify