SyntaxError: неожиданный токен [Char] в JSON в позиции 650xx

Когда я иду сохранить файл в формате JSON из приложения Javascript, которое я создаю (запускаю его на Node v6.11.0 с Express на моем локальном компьютере, порт 3000), я иногда получаю сообщение об ошибке:

SyntaxError: Неожиданный токен l в JSON в позиции 65032, где «токен» - это любой символ, который, как я полагаю, является последним символом перед усечением JSON, и где «позиция» всегда кажется «650xx», иногда даже до 65029. , иногда до 65036.

Когда я удаляю какой-то контент в файле, так что он предположительно поступает меньше этой длины, он отлично сохраняется, поэтому я полагаю, что я достиг какого-то ограничения длины по умолчанию, но откуда, я не могу сказать. Поиск, который я провел по этому вопросу, похоже, указывает на то, что ограничения на длину JSON находятся, по крайней мере, в диапазоне МБ, а самый большой файл, который я сохранил, составляет 104 КБ. Между тем ограничения, которые я нахожу в Node.js, если они есть, также находятся в диапазоне МБ, по крайней мере.

Сохраняемый мной 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.info( httpRequest );

    updateUserFilesList();
}; 

где circRefFilter - это массив строк, который используется для фильтрации того, какие пары ключ / значение включаются в отправляемый JSON.

На стороне сервера я делаю следующее:

router.post('/saveCognition', function( req, res, next ) { console.info( 'Accessing the Save Cognition route...' );
                        next(); 
                    },
                    function( req, res, next ) { 
                        req.on( 'error', function(){
                            console.info( 'error!' );
                        });
                        req.on( 'data', function( data ) {
                            console.info( 'data at router.post: ', data );

                            var jParsed = JSON.parse( data );
                            console.info( 'data parsed: ', jParsed );

                            jsonMethods.saveCognitionJson( jParsed.fullpath, jParsed.data );
                        });
                        req.on( 'end', function(){
                            console.info( 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.info( 'Accessing the Save Cognition route...' );
                        next(); 
                    },
                    function( req, res, next ) { 

                        let reqData = [];
                        let buffer;

                        req.on( 'error', function(){
                            console.info( 'error!' );
                        });
                        req.on( 'data', function( data, chunk ) {

                            reqData.push( chunk );

                            console.info( 'data at router.post: ', data );

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

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

                            var jParsed = JSON.parse( /* data */ buffer );
                            console.info( 'data parsed: ', jParsed );

                            jsonMethods.saveCognitionJson( jParsed.fullpath, jParsed.data );                            

                            console.info( req );
                        });
                        next();
                    },
                    function( req, res ) {
                        res.send('save the current cognition file!'); 
                    } 
                    );

Видимо, я неправильно конкатенирую. удаление .toString() не помогает. Спасибо.


Что ж, ОБНОВЛЕНИЕ со второй ошибкой оказалось простым исправлением. Смотрите мой ответ ниже. Спасибо @PatrickEvans за помощь в комментариях.

.on('data'... вызывается несколько раз (т. Е. Ваши данные поступают кусками), продолжайте объединять data, а затем выполните синтаксический анализ в .on('end'.
Patrick Evans 22.11.2018 01:24

@PatrickEvans ... почти готов, но ... см. Мою правку выше. Я, по-видимому, как-то неправильно конкатенирую.

Mark Scott Lavin 22.11.2018 02:33

@PatrickEvans не обращает внимания на последний комментарий. Я только что заработал. Вторая проблема заключалась в том, что я пытался вставить «кусок» в качестве второго параметра, который был пуст. Спасибо за помощь.

Mark Scott Lavin 22.11.2018 02:38
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
216
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

С помощью @PatrickEvans в комментариях к моему вопросу и помощи внешнего учебника здесь https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/ я смог понять это.

Как сказал Патрик:

.on('data'... gets called multiple times (ie your data comes in chunks), keep concatenating data then do the parse in .on('end'

Мне потребовалась минута, чтобы понять, как выполнить конкатенацию, но вот соответствующий рабочий код на стороне сервера.

router.post('/saveCognition', function( req, res, next ) { console.info( 'Accessing the Save Cognition route...' );
                        next(); 
                    },
                    function( req, res, next ) { 

                        let reqData = [];
                        let buffer;

                        req.on( 'error', function(){
                            console.info( 'error!' );
                        });
                        req.on( 'data', function( data ) {

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

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

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

                            var jParsed = JSON.parse( buffer );
                            console.info( 'data parsed: ', jParsed );

                            jsonMethods.saveCognitionJson( jParsed.fullpath, jParsed.data );                            

                            console.info( req );
                        });
                        next();
                    },
                    function( req, res ) {
                        res.send('save the current cognition file!'); 
                    } 
                    ); 

Другие вопросы по теме