You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 15:18:28