Хобрук: Ваш путь к мастерству в программировании

как найти причину SyntaxError: JSON.parse: неожиданный символ

Это ошибка, которую я получаю:

введите здесь описание изображения

Рассматриваемая строка в неминифицированном файле javascript jQuery 1.7.2:

 error: function( msg ) {
     throw new Error( msg );
 }, 

Отсюда невозможно понять, где ошибка (или, по крайней мере, мне не ясно). Я обнаружил, что раскомментирование этой строки из подключаемого модуля jQuery (http://shama.github.com/jmpress.js/#/docs) приводит к остановке ошибки:

$("#my_div").jmpress();

но я не могу получить большую степень детализации, чем это. Любые советы по отладке, которые помогут мне узнать, где происходит этот разбор JSON?

=== ИЗМЕНИТЬ: ===

используя JSON.parse, я смог отследить эту конкретную строку, которая пыталась быть проанализирована как строка:

_FB_f3757ad5f032398xd_action=proxy_ready&data

но не могу понять, где она входит в мой код, но из префикса "FB" кажется, что эта строка является частью Facebook JS SDK (который я использую)


  • @RobW: Чтобы уточнить: (function(){var _jp = JSON.parse; JSON.parse=function(a){console.log(a);return _jp.call(JSON,a)}}()). Это console.log будет пытаться разобрать JSON. 10.08.2012
  • Попробуйте проверить свой JSON: jsonlint.com 10.08.2012
  • У вас есть идеи, откуда берется этот JSON? 10.08.2012
  • @Ракета - это здорово! Я нашел плохой JSON с этим. но я понятия не имею, где он анализируется/где я могу найти точку для разбора JSON в коде... какие-нибудь подсказки, как это сделать? 10.08.2012
  • Это не синтаксический анализ, о котором вам нужно беспокоиться. Разбор безупречный. Вам нужно исправить JSON, который вы ему передаете. 10.08.2012
  • @Esailija - да, это то, что я имел в виду. 10.08.2012
  • @Rocket, проблема должна быть связана с Facebook - вот откуда исходит _FB_. но в плагине jmpress нет кода facebook, что странно 10.08.2012
  • @RobW - куда вы передаете функцию (function(){var _jp = JSON.parse; JSON.parse=function(a){console.log(a);return _jp.call(JSON,a)}}() ) JSON? Я бы предположил, что вы предоставите JSON вместо JSON в _jp.call(JSON,a), однако JSON имеет то же имя, что и функция. Можете ли вы уточнить? 24.10.2012
  • @ user66001 Эта строка кода сама по себе ничего не анализирует. После запуска этого фрагмента кода вызовы JSON.parse регистрируются в консоли без нарушения существующего кода. 25.10.2012
  • @RobW Спасибо, теперь понял. Я пробовал, и все, что он печатает, это то, что я могу получить от catch (err), есть ли способ найти, какую часть JSON он не может проанализировать (например, номер строки)? 25.10.2012
  • @user66001 user66001 Вы можете добавить внутрь оператор debugger;. Затем, когда инструменты разработчика (Chrome) открыты, вы можете проверить трассировку вызовов, проверить локальные/замыкающие/глобальные переменные, а также увидеть точное местоположение кода. Другой вариант - поставить console.trace(); 25.10.2012
  • @RobW - Спасибо. Выяснилось, что JSON иногда доставляется с тегами ‹pre›, которые не отображаются при загрузке страницы JSON, а View Source кажется недоступным, несмотря на тот факт, что разметка анализируется! (В противном случае я бы предупредил JSON! :()... Благодарю за помощь! 25.10.2012

Ответы:


1

Хорошо, глядя на исходный код jmpress, он исходит из обмена сообщениями iframe из разных источников. В основном jmpress делает это:

window.addEventListener("message", function(event) {
    // We do not test orgin, because we want to accept messages
    // from all orgins
    try {
        var json = JSON.parse(event.data);
        switch(json.type) {
        case "select":
            // TODO SECURITY filter targetId
            $.each(eventData.settings.presentationMode.transferredValues, function(idx, name) {
                eventData.current[name] = json[name];
            });
            $(eventData.jmpress).jmpress("select", {step: "#"+json.targetId, substep: json.substep}, json.reason);
            break;
        case "listen":
            current.selectMessageListeners.push(event.source);
            break;
        case "ok":
            clearTimeout(current.presentationPopupTimeout);
            break;
        case "read":
            try {
                event.source.postMessage(JSON.stringify({type: "url", url: window.location.href, notesUrl: eventData.settings.presentationMode.notesUrl}), "*");
            } catch(e) {
                $.error("Cannot post message to source: " + e);
            }
            break;
        default:
            throw "Unknown message type: " + json.type;
        }
    } catch(e) {
        $.error("Recieved message is malformed: " + e);
    }
});

Таким образом, все фреймы, которые отправляются в главное окно, будут проходить через этот обработчик событий и регистрировать ошибку, когда они передают недопустимый JSON. Похоже, что на вашем веб-сайте есть iframe facebook, который отправляет сообщения в главное окно. Попробуйте удалить все это и посмотреть, исчезнут ли ошибки.

09.08.2012
  • ага! удаление Facebook SDK устраняет ошибки... к сожалению, мой сайт также ломается другими способами, ха-ха. Можно ли как-то заставить эти две вещи хорошо играть вместе? возможно, я мог бы просто заставить jmpress молча игнорировать плохой JSON? (не знаю, почему Facebook считает, что в любом случае можно передавать недопустимый JSON...) 10.08.2012
  • @lol: вы можете отправить любое сообщение между рамкой и окном. Это не обязательно должен быть JSON. Проблема в том, что jmpress (ошибочно) предполагает, что это должен быть JSON. 10.08.2012
  • @lol Дело не в том, что Facebook пытается даже передать JSON. дело в том, что jmpress создает универсальный обработчик сообщений, который думает, что все в формате JSON. Как говорится в комментарии к коду, он не делает различий между источниками iframe, он просто берет что угодно. 10.08.2012
  • @lol, вы можете отредактировать исходный код jmpress, чтобы он не выдавал ошибку и просто молча терпел неудачу. Удалить эту строку $.error("Recieved message is malformed: " + e); 10.08.2012
  • @lol: Ошибка ломает страницу? Может быть, вы можете просто игнорировать это :-P 10.08.2012
  • да, я вижу ваши точки. Я чувствую себя в безопасности, просто комментируя эту $.error строчку. после этого все нормально работает. и последнее - что такое сообщения javascript? я хотел бы узнать о них больше 10.08.2012
  • @lol это безопасный способ для двух фреймов из разных источников общаться друг с другом на странице. Обычно 2 фрейма из разных источников не могут ничего сделать друг с другом из-за одной и той же политики происхождения. Благодаря обмену сообщениями iframe обе стороны могут реализовать API обмена сообщениями как безопасный способ общения друг с другом. См. developer.mozilla.org/en-US/docs/DOM/window. .postMessage 10.08.2012
  • @Esailija очень круто. какие-нибудь мысли о том, зачем jmpress нужна связь между источниками? поскольку это плагин github, он не запускает контент с другого сервера, не так ли? это просто эмулятор презентации слайдов.. 10.08.2012
  • @lol Я уверен, что у них есть свои причины требовать обмена данными между iframe из разных источников, но я вообще не знаком с плагином, и это не сразу видно из их документации. 10.08.2012
  • Новые материалы

    От AlphaGo до самоуправляемых автомобилей: понимание основ обучения с подкреплением
    Руководство для начинающих по RL! Готовы ли вы исследовать передовые технологии искусственного интеллекта? Откройте для себя захватывающий мир обучения с подкреплением ! От ошеломляющей победы..

    Как сделать все элементы равными из списка в минимальных операциях в Python, используя math.ceil()
    Сегодня мы узнаем, как найти минимальные операции, необходимые для того, чтобы сделать все элементы из списка равными, используя Python в качестве языка программирования. Я использую PyCharm в..

    Создание пользовательских событий в React Native
    Обновление: это решение больше не работает, поскольку React Native не включает стандартную библиотеку Node. Однако есть автономные модули, в которых реализован API EventEmitter. Рассмотрите..

    За кулисами метода JavaScript Array.filter()
    Array.filter() — это встроенный в JavaScript метод, который создает новый массив со всеми элементами исходного массива, прошедшими определенный тест. Метод не изменяет исходный массив...

    Прогресс с моделью скрытой диффузии, часть 3 (машинное обучение)
    Выровняйте свои латентные данные: синтез видео высокого разрешения с моделями скрытой диффузии (arXiv) Автор: Андреас Блаттманн , Робин Ромбах , Хуан Линг , Тим Докхорн , Сын Ук Ким ,..

    Totaljs Flow: триггерные компоненты
    Total.js — это мощная и универсальная среда веб-приложений, которая предоставляет разработчикам ряд инструментов для оптимизации процесса разработки. Total.js Flow — самый популярный..

    Сквозное машинное обучение BigQuery
    Используйте Google Cloud BigQuery для участия в конкурсе Kaggle Я покажу вам, как прогнозировать выживших после катастрофы Титаника, используя только BigQuery и API Kaggle . С тех пор, как я..