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

Android WebView自定义错误页时返回上一页加载错误页的解决方法

解决WebView返回键加载历史错误页的问题

这个问题我做WebView开发时也踩过坑,核心原因是你加载自定义错误页的方式会默认把它添加到WebView的历史栈里,导致按返回键时优先回到错误页,而不是你期望的上一个正常页面。下面给你几个实用的修复方案:

方案一:加载错误页时不加入历史栈(推荐)

默认用loadUrl加载错误页会自动把页面加入历史记录,改用loadDataWithBaseURL方法,通过设置最后一个参数为null,就能阻止错误页进入历史栈。

修改你的onReceivedError方法:

public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
    super.onReceivedError(view, errorCode, description, failingUrl);
    requestLink = failingUrl;
    
    try {
        mWebView.stopLoading();
    } catch (Exception e) {
        Log.e(FLAG, e.toString());
    }
    
    // 替换成你的自定义错误HTML内容
    String customErrorHtml = "<html><head><style>body{text-align:center;margin-top:50px;}</style></head>" +
                            "<body><h2>页面加载失败</h2><p>" + description + "</p></body></html>";
    
    // 关键:最后一个参数传null,不将错误页加入历史栈
    mWebView.loadDataWithBaseURL(null, customErrorHtml, "text/html", "UTF-8", null);
}

这样处理后,WebView的历史栈里就不会保存错误页,按下返回键时会直接回到之前的正常页面。

方案二:重写返回键逻辑,跳过错误页

如果不想修改错误页的加载方式,可以在Activity/Fragment的返回键处理逻辑里,主动判断并跳过历史中的错误页。

示例代码:

@Override
public void onBackPressed() {
    if (mWebView.canGoBack()) {
        WebBackForwardList historyList = mWebView.copyBackForwardList();
        int currentPos = historyList.getCurrentIndex();
        
        // 检查上一条历史记录是否是错误页
        if (currentPos > 0) {
            WebHistoryItem prevItem = historyList.getItemAtIndex(currentPos - 1);
            // 这里根据你的错误页特征判断,比如错误页是本地加载的data URL,或者你自定义的标记URL
            boolean isErrorPage = prevItem.getUrl().startsWith("data:text/html") 
                                 || prevItem.getUrl().equals("你自定义的错误页URL");
            
            if (isErrorPage) {
                // 直接后退两步,跳过错误页
                mWebView.goBackOrForward(-2);
                return;
            }
        }
        // 正常后退到上一页
        mWebView.goBack();
    } else {
        // 没有历史记录时,执行默认返回逻辑
        super.onBackPressed();
    }
}

这种方式需要你能准确识别错误页的特征,比如如果你的错误页是用loadData加载的,它的URL通常是data:text/html,...格式,以此作为判断依据。

方案三:精准捕获HTTP错误(API 23+)

如果你的App最小兼容版本是API 23及以上,可以用onReceivedHttpError替代部分onReceivedError的场景,它只捕获HTTP状态码错误(如404、500),避免误处理其他类型的错误,同时结合方案一的方式不加入历史栈:

@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
    super.onReceivedHttpError(view, request, errorResponse);
    // 加载自定义错误页,不加入历史栈
    String errorHtml = "<html><body><h1>HTTP加载错误:" + errorResponse.getStatusCode() + "</h1></body></html>";
    view.loadDataWithBaseURL(null, errorHtml, "text/html", "UTF-8", null);
}

总结

优先推荐方案一,它从根源上避免错误页进入历史栈,逻辑更简洁,也不需要额外的判断逻辑。如果有兼容旧版本的需求,方案二也是可靠的选择。

内容的提问来源于stack exchange,提问作者Danielzz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:27:30