PrimeFaces中p:schedule快速移除时Ajax请求缺失ViewState问题求助
解决方案:PrimeFaces p:schedule未初始化完成被移除导致的无效Ajax请求问题
针对JSF 2.3、PrimeFaces 8环境下,homeTabs:widgetContent-LEAVE_CALENDAR:lvCalendarForm:schedule组件在脚本未执行完就被快速移除,引发缺少ViewState的无效Ajax请求问题,提供以下三种可行方案:
1. 前端拦截无效Ajax请求
通过监听PrimeFaces的Ajax发送事件,在请求发出前校验组件是否仍存在于DOM中,不存在则终止请求:
$(document).on('pfAjaxSend', function(e, xhr, settings) { // 解析请求中的组件ID var sourceMatch = settings.data.match(/javax.faces.source=([^&]+)/); if (!sourceMatch) return; var sourceId = sourceMatch[1]; // 转义JSF组件ID的冒号,适配DOM选择器 var escapedId = sourceId.replace(/:/g, '\\:'); var sourceElement = document.getElementById(escapedId); // 组件不存在则终止请求 if (!sourceElement) { xhr.abort(); } });
2. 控制组件移除时机,确保初始化完成
给p:schedule绑定初始化完成标记,移除组件前校验该状态,未完成则延迟执行移除操作:
页面代码:
<p:schedule id="schedule" widgetVar="scheduleWidget" onInit="PF('scheduleWidget').initialized = true;" />
移除逻辑代码:
function removeScheduleContainer() { var scheduleWidget = PF('scheduleWidget'); // 校验组件已初始化完成 if (scheduleWidget && scheduleWidget.initialized) { // 执行移除容器的操作,示例: $('#homeTabs\\:widgetContent-LEAVE_CALENDAR').remove(); } else { // 未初始化完成则延迟100ms重试 setTimeout(removeScheduleContainer, 100); } }
3. 服务器端过滤无效请求
自定义JSF过滤器,校验Ajax请求的组件来源有效性及ViewState存在性,直接拦截无效请求:
@WebFilter(filterName = "InvalidAjaxRequestFilter", urlPatterns = {"*.xhtml"}) public class InvalidAjaxRequestFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; // 仅处理Ajax请求 if ("partial/ajax".equals(req.getHeader("Faces-Request"))) { String sourceId = req.getParameter("javax.faces.source"); FacesContext facesContext = FacesContext.getCurrentInstance(); // 校验请求来源组件是否存在于当前视图 if (sourceId != null && facesContext.getViewRoot().findComponent(sourceId) == null) { sendInvalidResponse((HttpServletResponse) response, "Invalid component source"); return; } // 校验ViewState是否存在 String viewState = req.getParameter("javax.faces.ViewState"); if (viewState == null || viewState.trim().isEmpty()) { sendInvalidResponse((HttpServletResponse) response, "Missing ViewState"); return; } } chain.doFilter(request, response); } private void sendInvalidResponse(HttpServletResponse response, String message) throws IOException { response.setStatus(HttpServletResponse.SC_BAD_REQUEST); response.setContentType("text/plain"); response.getWriter().write(message); } @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void destroy() {} }
内容的提问来源于stack exchange,提问作者Best_Name
相关产品推荐
相关产品推荐

