SyntaxError:JSON在位置650xx处出现意外令牌[Char]

时间:2018-11-22 00:09:28

标签: javascript node.js json stringify

当我从正在构建的Javascript应用程序中保存JSON格式的文件时(在本地计算机上的Express 3000的Node v6.11.0上运行它,在本地计算机上,端口3000),有时会出现错误:

SyntaxError:JSON中意外的令牌l在位置65032,其中“令牌”是我认为是截断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字符串长度限制,我确实知道将文件分块发送可能有意义,但是我不确定这是否是解决方案,或者如何解决这样做。

帮助表示赞赏。

谢谢!


以下帕特里克·埃文斯的第一笔报价的更新。

可能到达那里,但是...我现在得到了错误

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在评论中对此提供的帮助。

1 个答案:

答案 0 :(得分:0)

借助@PatrickEvans对我的问题的评论,以及此处https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/的外部教程的帮助,我得以弄清楚这一点。

如Patrick所说:

  

.on('data'...被调用多次(即您的数据进入   块),继续连接数据,然后在.on('end'

花了我一分钟才弄清楚如何进行串联,但这是相关的工作服务器端代码。

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 ) {

                            reqData.push( data );
                            console.log( 'data at router.post: ', data );

                        });
                        req.on( 'end', function(){

                            buffer = Buffer.concat( reqData ).toString();

                            var jParsed = JSON.parse( 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!'); 
                    } 
                    );