Инструменты разработчика · JSON форматировщик и валидатор
Невидимые символы, нарушающие JSON: BOM, смарт-кавычки и NBSP.
· Как это работает
JSON рабочий процесс разработчика проверка
Когда валидатор сообщает об ошибке на самом первом символе и файл выглядит идеально, обычно виноват невидимый символ. В этом посте объясняются знаки порядка байтов, типографские кавычки и неразрывные пробелы, а также способы сообщения о каждом из них.
Строка 1, столбец 1, ничего плохого не видно
Строка 1, столбец 1, ничего страшного — документ JSON может начинаться с символа, который занимает реальную позицию, но отображается без видимого глифа. Тогда открывающая скобка будет первой, даже если ей предшествует знак порядка байтов или символ нулевой ширины. Строгий синтаксический анализатор обнаруживает эту скрытую кодовую точку до того, как она достигнет `{`, поэтому сообщение о первом столбце является точным, а не расплывчатым. Дисплей и последовательность персонажей просто рассказывают разные истории.
Не удаляйте фигурную скобку, которая выглядит правильно только потому, что рядом с ней появляется курсор. Проверьте кодовую точку по указанному смещению, включите видимые пробелы или переключитесь на шестнадцатеричное представление. ToolAcre не удаляет автоматически ведущий BOM перед анализом, и его сканер сообщает о первом неожиданном символе.
Знак порядка байтов UTF-8.
Метка порядка байтов UTF-8 — последовательность байтов EF BB BF декодируется в U+FEFF в начале файла. Порядок байтов в UTF-8 не является двусмысленным, поэтому этот знак не нужен, но некоторые редакторы и инструменты экспорта по-прежнему добавляют его в качестве сигнатуры кодировки. RFC 8259 говорит, что генераторы JSON не должны добавлять BOM к сетевому JSON, хотя анализаторы могут игнорировать его для совместимости. Эту толерантность нельзя предполагать в отношении разных инструментов.
В строке JavaScript BOM представляет собой один символ, хотя его представление UTF-8 использует три байта. ToolAcre сообщает о позициях в строковых символах, поэтому в строке 1, столбце 1 появляется ведущий знак. Настройте редактор на сохранение UTF-8 без BOM или удалите U+FEFF перед распространением файла.
Умные цитаты из текстовых процессоров
Умные кавычки из текстовых процессоров — типографские открывающие и закрывающие знаки выглядят безупречно в прозе, но JSON распознает только кавычку ASCII U+0022 в качестве разделителя строк. U+201C и U+201D — обычные символы Юникода. Вне строки они не могут начинаться с имени или значения свойства, поэтому валидатор сам сообщает смарт-кавычку. Автокоррекция в чате, электронной почте или редакторе документов часто вносит изменения после того, как JSON изначально был действительным.
Замените разделители прямыми двойными кавычками, затем проверьте апострофы и кавычки, относящиеся к значению. Фигурные кавычки совершенно законны в качестве содержимого внутри правильно разделенной строки JSON, например `"She said “go”"`; они терпят неудачу только тогда, когда их просят выполнить грамматическую работу разделителя.
Неразрывные пробелы и символы нулевой ширины
Неразрывные пробелы и символы нулевой ширины — JSON пробелы — это намеренно короткий список: обычный пробел U+0020, табуляция U+0009, перевод строки U+000A и возврат каретки U+000D. Неразрывный пробел U+00A0 может выглядеть идентично обычному пробелу между двоеточием и значением, но его нет в этом списке. Пробел нулевой ширины U+200B вообще ничего не отображает, но остается неожиданным символом вне строки в кавычках.
Веб-страницы используют неразрывные пробелы для объединения слов, а системы обмена сообщениями могут вставлять символы нулевой ширины для переноса или обработки сценариев. Копирование форматированных фрагментов может перенести их в конфигурацию. Замените структурные символы NBSP обычными пробелами и удалите непреднамеренные символы нулевой ширины, руководствуясь указанным смещением.
Рабочий пример: конфигурация, скопированная из сообщения чата.
Рабочий пример: конфигурация, скопированная из сообщения чата — предположим, что видимый текст похож на `{"mode": "safe"}`, но проверка не удалась в начале. Шестнадцатеричный вид показывает EF BB BF перед скобой. Удаление этого BOM переводит следующий отчет в цитату перед `mode`, которая на самом деле является U+201C. Замена обоих интеллектуальных разделителей на U+0022 приводит к появлению U+00A0 между двоеточием и значением.
Измените это структурное неразрывное пространство на U+0020 и подтвердите еще раз. Принятый результат теперь можно отформатировать обычным образом. Эта последовательность показывает, почему ненадежно восстанавливать только то, что отображается на экране: несколько невидимых или похожих символов могут занимать разные грамматические позиции. Проследите за каждой строкой и столбцом, определите фактическую точку кода, сделайте одну намеренную замену и повторите проверку.
Как увидеть невидимое
Как увидеть невидимое — включите в редакторе опцию рендеринга пробелов, чтобы отличать табуляцию от пробелов и выявлять необычные пробелы, а затем используйте инспектор Юникода или шестнадцатеричное представление для символов, которые по-прежнему выглядят одинаково. UTF-8 BOM отображается как EF BB BF, неразрывный пробел — как C2 A0, а пробел нулевой ширины — как E2 80 8B. Умные котировки открытия и закрытия отображаются как E2 80 9C и E2 80 9D.
Перед подсчетом сопоставьте систему координат диагностики. ToolAcre сканирует строку JavaScript, поэтому ее столбцы учитывают UTF-16 кодовых единиц, а не UTF-8 байт. Поэтому байт-ориентированный шестнадцатеричный редактор может отображать большее числовое смещение после символов, отличных от ASCII. Используйте указанную строку, чтобы сузить поиск, проверять соседние кодовые точки и переводить только по мере необходимости.
Что это не распространяется
Чего это не касается — моджибаке, такой как `café`, может быть полностью допустимым JSON. Анализатор видит обычную последовательность строковых символов и не имеет доказательств того, что UTF-8 байт ранее были декодированы как другая кодировка. Аналогично, неразрывный пробел или символ нулевой ширины внутри значения в кавычках являются синтаксически допустимыми. При проверке выявляются символы, нарушающие грамматику JSON; он не может решить, соответствует ли допустимый контент Unicode замыслу автора.
Устраните повреждение кодировки на границе, где байты становятся текстом, используя знания об исходной и ошибочной кодировке. Не кодируйте и не декодируйте строку JSON повторно, пока она не станет выглядеть лучше, поскольку это может повредить и без того правильные символы. Нормализация на уровне приложения также является отдельным решением: визуально идентичные последовательности Юникода могут сравниваться по-разному, оставаясь при этом действительными.
Вывод: доверяйте столбцу, о котором сообщается, даже если строка выглядит чистой
Вывод: доверяйте столбцу, о котором сообщается, даже если строка выглядит чистой — невидимые символы и похожие знаки препинания по-прежнему занимают точные позиции в источнике. Ведущий BOM, фигурный разделитель, неразрывный пробел или знак нулевой ширины могут помешать синтаксическому анализатору достичь скобки или кавычки, которые кажутся правильными. Выявите пробелы, проверьте кодовые точки или байты и замените символ, идентичность которого противоречит его грамматической роли, вместо того, чтобы случайно редактировать соседний видимый JSON.
Помните, что позиции могут считать символы, в то время как шестнадцатеричный инструмент считает закодированные байты, поэтому сравнивайте окружающий текст, а не ожидайте совпадения каждого числа смещения. Удалите BOM только на границе документа, преобразуйте интеллектуальные разделители в U+0022 и замените недопустимые структурные интервалы, не удаляя законный Unicode внутри строк.