Поведение браузера Страница UTF-8 с дополнительным символом, например U+FFFE (ОШИБКА по ajax) Ошибка синтаксического анализа XML: неправильно сформирован

Мы разрабатываем некоторые веб-приложения JSF с помощью PrimeFaces.

В inputText можно скопировать/вставить текст с символом, отличным от UTF-8, например `` (Вот символ), и сохранить страницу. Но в отрисованном HTML есть ошибка:

Ошибка: запрещенная кодовая точка U+fffe.

Браузер не показывает (скрывает) ошибку, а показывает символ, отличный от UTF-8 (работает как в обычном случае)!

Но после того, как эта страница будет отправлена ​​с сервера в браузер в ответе Ajax, браузер показывает ошибку в консоли! И пользователь может увидеть ошибку!

Сообщение консоли:

Ошибка синтаксического анализа XML: неправильно сформирован

Как лучше всего справиться с этой ошибкой?

У меня много плохих идей. :)

  1. Подтвердите ввод перед сохранением!

    • Клиентская часть с Javascript может быть общей, но не безопасной.
    • Замена недопустимых символов на '' может вызвать непонимание со стороны пользователя. Есть много плохих персонажей, похожих на персонажей с правым акцентом.
    • Я могу сделать валидатор для JSF, но мне придется зарегистрировать его во всех inputText компонентах один за другим.
  2. Возможно, я смогу найти Javascript, который анализирует ответы Ajax, и исправить его.

«Минимальное» воспроизведение:

Ссылка на Github

  1. Скачать исходный код
  2. чистый пакет mvn
  3. скачайте wildfly 32.0.1.Final
  4. скопируйте войну из цели проекта в wildfly/standalone/deployments
  5. начать дикую полет
  6. http://localhost:8080/utf8/main.xhtml
  7. После копирования вставьте плохой символ и нажмите кнопку, это не удалось.

Я думаю, основная проблема в том, что Ajax использует XML. И в UTF-8 есть много символов, которые недопустимы в XML.

Как я могу быстро проверить свою строку в Java, если есть недопустимые символы?

Некоторые другие события

Есть странное поведение. Символ U+0002 удален автором JSF.

  1. Я набираю U+0002 и нажимаю кнопку
  2. Установлено свойство bean-компонента на стороне сервера.
  3. Но на этапе renderResponse логика записи Html удалила этот символ.

С U+FFFE характер другой. Я написал валидатор, и он выдает ValidatorException, но на этапе renderResponse появился символ U+FFFE.

Я думаю, что эта ошибка модхарры может быть очень идентичной:

https://github.com/eclipse-ee4j/mojarra/issues/4516

Я сделал свою репродукцию с дикими мухами и праймфейсами.

László Tóth 21.07.2024 23:46

Это похоже на BOM, который должен отображаться в UTF8.

Bergi 21.07.2024 23:53

`` (U+FFFE, не определено) или `` (U+FEFF, неразрывное пространство нулевой ширины, или знак порядка байтов)?

JosefZ 25.07.2024 20:37

«символ, отличный от UTF-8» — такого понятия не существует. UTF-8 — это просто кодировка Unicode. На самом деле вы имеете в виду «символ, отличный от Юникода», и действительно, U+FFFE не определен в Юникоде, но он полностью кодируется в UTF-8 как байты 0xEF 0xBF 0xBE. Кроме того, U+FFFE является недопустимым символом в XML, в спецификации очень четко указано, какие именно символы Юникода разрешены: «любой символ Юникода, за исключением суррогатных блоков, FFFE и FFFF». Поэтому просто отфильтруйте их из своей строки.

Remy Lebeau 25.07.2024 21:26
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
150
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Я воспроизвел это. Проблема двойная. Это действительно ошибка в Mojarra, которая, в свою очередь, выявила еще одну ошибку в обработчике Ajax PrimeFaces. Я создал новую задачу на стороне Мохарры: https://github.com/eclipse-ee4j/mojarra/issues/5464.

Я думаю, что эта ошибка модхарры может быть очень идентичной:
https://github.com/eclipse-ee4j/mojarra/issues/4516

Да, в самом деле. Пару лет назад я исправил аналогичную проблему для реализации Mojarra, однако она касалась другого диапазона Юникода.

На данный момент вы можете обойти эту проблему, используя MyFaces вместо Mojarra (я подтвердил, что в MyFaces он работает нормально) или используя Standard Faces Ajax вместо PrimeFaces Ajax следующим образом:

<p:commandButton value = "Click" action = "#{hello.ajax}">
    <f:ajax execute = "@form" render = "@form" />
</p:commandButton>

Тем не менее,

символ, отличный от UTF-8

если бы это действительно не был символ UTF-8 (U означает Unicode), он не был бы указан на веб-сайте, посвященном символам Unicode...;)

Не касаясь конкретной проблемы, я заметил, что шаблон XHTML в вашем репродукторе https://github.com/halcsi19790320/ajax-utf8-problem/blob/main/src/main/webapp/main.xhtml имеет много ненужных тегов/атрибутов, которые вы, скорее всего, пытались использовать для решения проблемы.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html ...accept-charset = "utf-8">
    <h:head>
        <meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" />
    </h:head>

Могу заверить, что ничего из этого не имеет отношения к делу. XML-пролог не нужен ни для Facelets, ни для средней IDE. Тип документа XHTML не нужен, если клиент в конечном итоге получает простую HTML-страницу. Устаревший атрибут accept-charset игнорируется современными браузерами (последним, кто воспринял его всерьез, был Internet Explorer). <meta http-equiv> игнорируется, когда HTML-страница обслуживается по протоколу http(s)://, а не по протоколу, например. file://. Следующий шаблон HTML5 содержит меньше шума и отлично работает:

<!DOCTYPE html>
<html ...>
    <h:head>

    </h:head>

См. также Поддержка JavaServer Faces 2.2 и HTML5, почему до сих пор используется XHTML и принцип KISS.

Спасибо, остальные замечания тоже. Джакарта, лица HtmlUtils вырезали множество непечатаемых символов, я думаю, что можно решить лучше. Нет? «Плохие» символы — это просто u+FFFE и u+FFFF? Или они есть?

László Tóth 26.07.2024 13:54

Я много думал, что может быть лучшим решением перед патчем prime/jsf... 1. Конвертер, который обрезает все входные эти символы, отличные от XML, или 2. Валидатор по умолчанию + фильтр, такой как ошибка mojarra, который удаляет эти символы из частичного ответ?

László Tóth 26.07.2024 13:56
github.com/primefaces/primefaces/issues/12331
László Tóth 26.07.2024 14:20

В конце концов, это действительно ошибка в Мохарре. Смотрите обновленный ответ.

BalusC 26.07.2024 14:53

И последний аспект. После этого решения недопустимые бесполезные символы XML могут быть установлены для поддержки bean-компонентов, сущностей и таблиц БД из компонентов ввода на основе строк. Я правда, что они удалены из частичного ответа, но после сохранения, ajax get и ajax post эти символы удаляются невидимыми с сервера (второе сохранение удаляет их). Если я использую валидатор, я не могу писать неправильные символы в сообщении, а затем сохранить сообщение, исчезающее (поскольку они исключены). Я думаю, что лучший способ справиться с этим - ServletFilter, который удаляет все «плохие» символы из requestMap или преобразователя строк jsf. Каково твое мнение?

László Tóth 27.07.2024 14:17

Для этого вы можете использовать глобальный преобразователь строк Faces.

BalusC 27.07.2024 16:20

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