JSF нет запроса на перенаправление после ввода файла ajax
У меня есть форма в JSF 2.2:
<h:form enctype="multipart/form-data">
<h:outputLabel>title *</h:outputLabel>
<h:inputText value="#{bean.title}" required="" />
<h:outputLabel>Image *</h:outputLabel>
<h:inputFile value="#{bean.picutreFile}" a:accept="image/*">
<f:ajax listener="#{bean.uploadPicture}" />
</h:inputFile>
<h:commandLink action="#{bean.save}">
Save
</h:commandLink>
</h:form>
Функции:
public String save() {
return "/index?faces-redirect=true";
}
public void uploadPicture() {
// Do nothing
}
Но после того, как я выберу изображение и получу вызов uploadPicture
функция, save
функция не может перенаправить страницу. Призывает save
но перенаправление не работает, и просто обновите текущую страницу.
Если я пропускаю загрузку файла, он перенаправляется нормально. Как я могу заставить его работать?
РЕДАКТИРОВАТЬ
Я заметил, что если я уберу Аякс <f:ajax listener="#{bean.uploadPicture}" />
это работает как ожидалось. Но я должен иметь этот ajax, потому что я хочу отобразить изображение после загрузки.
РЕДАКТИРОВАТЬ 2
Я вижу, что после вызова ajax JSF создает странный iframe внизу страницы с partial-response
тег в его теле, и когда я нажимаю "Сохранить", то iframe перенаправляет к месту назначения. Это почему??
2 ответа
Я воспроизвел это. Я согласен, что поведение сбивает с толку и не интуитивно понятно, но я бы не сказал, что это ошибка в реализации JSF, потому что вы по сути смешиваете ajax с обычными запросами, что в первую очередь неправильно. См. Также этот связанный вопрос httpError: Транспорт Http вернул код состояния 0.
Правильный подход - либо сделать командную ссылку ajax-ссылкой,
<h:commandLink action="#{bean.save}">
Save
<f:ajax execute="@form" />
</h:commandLink>
или удалить <f:ajax>
от <h:inputFile>
(и выполнить загрузку в save()
).
<h:inputFile value="#{bean.picutreFile}" a:accept="image/*" />
Тот самый iframe, который вы видите, - это давняя уловка для симуляции асинхронного поведения при загрузке файлов, изобретенная задолго до стандартизации API-интерфейса XHR2 / FormData. Этот подход был во время разработки JSF 2.2 предпочтительным по сравнению с XHR2 из-за лучшей обратной совместимости в браузерах (особенно в MSIE). Смотрите также ao Как сделать асинхронную (AJAX) загрузку файлов с помощью iframe?
Как я знаю, JSF блокирует ваш запрос до вызова ajax для обеспечения безопасности. Может быть, вы можете поставить панель обработки или что-то подобное во время вызова AJAX. Таким образом, пользователь не может нажать кнопку сохранения, пока не завершится вызов ajax.
Можете ли вы немного подождать после нажатия кнопки загрузки, затем нажмите кнопку Сохранить? Это должно работать, если я прав.