Это не работает, потому что здесь есть средство для состояния гонки.Два HTTP-запроса отправляются одновременно в одном и том же окне.Один ajax к серверу и один нормальный к данной ссылке.Тот, который заканчивается раньше, побеждает.Вы хотите отправлять HTTP-запросы синхронно.Сначала ajax на сервер, а когда он возвращает, , затем нормальный к данной ссылке.
Что касается вашего хакерского решения, оно работает, потому что использует JavaScript для открытия URL вновое окно вместо текущего и затем блокирует действие ссылки по умолчанию, поэтому обычный ответ просто приходит в совершенно отдельное окно, в то время как ответ ajax все еще приходит в исходное окно.Таким образом, в исходном окне больше нет условий состязания двух HTTP-запросов.
Что касается окончательного решения, это невозможно при стандартном наборе компонентов JSF 2.0.Использование <h:commandLink>
и последующее перенаправление действительно выполнимо, но эта ссылка не может быть найдена поисковыми роботами, и она эффективно запускает POST-запрос, который на IMO хуже, чем ваше новое оконное решение.
Если вы действительно хотите открыть ссылку в текущем окне, сохраняя целевой URL-адрес в ссылке на ссылку, то я бы предложил создать простой сервлет , который выполняет ссылкуотслеживание и перенаправление задания, и пусть jQuery манипулирует целевым объектом ссылки во время onclick
.
Примерно так:
<a rel="ext" id="ext_#{title.id}" href="#{title.link}">read more</a>
(идентификаторы HTML-элементов могут начинаться не с цифры! Следовательно,ext_
префикс, вы, конечно, можете изменить это как хотите.)
с
$(function() {
jQuery('a[rel=ext]').click(function(e) {
var link = jQuery(this);
var url = 'track'
+ '?id=' + encodeURIComponent(link.attr('id'))
+ '&url=' + encodeURIComponent(link.attr('href'));
if (link.attr('target') == '_blank') {
window.open(url);
} else {
window.location = url;
}
e.preventDefault();
});
});
и
@WebServlet(urlPatterns={"/track"})
public class TrackServlet extends HttpServlet {
@EJB
private TrackService trackService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getParameter("id");
String url = request.getParameter("url");
if (id == null || url == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
trackService.track(id.replaceAll("\\D+", "")); // Strips non-digits.
response.sendRedirect(url);
}
}