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

Android WebView导航时出现419 | Page Expired问题排查求助

Android WebView导航时出现419 | Page Expired问题排查

问题说明

使用Android WebView进行导航操作时,页面返回419 | Page Expired错误,相关代码如下:

@SuppressLint("SetJavaScriptEnabled")
fun loadWebview(url:String){

    var  webView:WebView = findViewById(R.id.webView)
    //begin new
    val webSettings = webView.settings
    webSettings.javaScriptEnabled = true
    webSettings.allowFileAccess = true
    webSettings.allowContentAccess = true
    webSettings.databaseEnabled = true
    webSettings.javaScriptCanOpenWindowsAutomatically = true

    //improve webView performance

    webView.settings.setRenderPriority(WebSettings.RenderPriority.HIGH)
    webView.settings.cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK
    webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
    webView.scrollBarStyle = View.SCROLLBARS_INSIDE_OVERLAY
    webSettings.domStorageEnabled = true
    webSettings.layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS
    webSettings.useWideViewPort = true
    webSettings.savePassword = true
    webSettings.saveFormData = true
    webSettings.setEnableSmoothTransition(true)

    webSettings.setDomStorageEnabled(true);

    webView.getSettings().setDomStorageEnabled(true);
    if (Build.VERSION.SDK_INT >= 21) {
        webSettings.mixedContentMode = 0
        webView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
    } else if (Build.VERSION.SDK_INT >= 19) {
        webView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
    } else {
        webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
    }
    webView.webChromeClient = WebChromeClient()

    CookieSyncManager.createInstance(this)
    CookieSyncManager.getInstance().startSync()
    val cookieManager: CookieManager = CookieManager.getInstance()
    cookieManager.setAcceptCookie(true)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true)
    }

    webView.loadUrl(url)

}

代码问题分析

419 Page Expired通常和后端的CSRF令牌验证失败有关,结合你的代码,主要问题如下:

  1. 缓存模式重复设置
    代码中先后设置了LOAD_CACHE_ELSE_NETWORK和LOAD_DEFAULT两种缓存模式,这会导致WebView的缓存逻辑混乱,可能加载了过期的页面内容或CSRF令牌,引发419错误。

  2. 过时的Cookie同步方式
    CookieSyncManager从API 21开始已被废弃,继续使用可能导致Cookie无法正确同步到WebView,使得请求时无法携带有效的CSRF令牌。

  3. 冗余的DOM存储设置
    代码中重复三次设置domStorageEnabled = true,虽然不直接引发错误,但属于无效冗余代码。

  4. 废弃的API调用
    savePassword从API 19开始已被废弃,保留该设置会产生警告,且无实际作用。

  5. 未设置WebViewClient
    缺少自定义的WebViewClient,页面导航时可能无法正确处理请求上下文,导致CSRF令牌等关键Cookie没有被正确携带到新请求中。

修复方案

针对上述问题,修改代码如下:

@SuppressLint("SetJavaScriptEnabled")
fun loadWebview(url: String) {
    val webView: WebView = findViewById(R.id.webView)
    val webSettings = webView.settings

    // 基础配置
    webSettings.javaScriptEnabled = true
    webSettings.allowFileAccess = true
    webSettings.allowContentAccess = true
    webSettings.databaseEnabled = true
    webSettings.javaScriptCanOpenWindowsAutomatically = true
    webSettings.domStorageEnabled = true

    // 性能优化配置
    webSettings.renderPriority = WebSettings.RenderPriority.HIGH
    webSettings.cacheMode = WebSettings.LOAD_DEFAULT // 统一缓存模式
    webView.scrollBarStyle = View.SCROLLBARS_INSIDE_OVERLAY
    webSettings.layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS
    webSettings.useWideViewPort = true
    webSettings.saveFormData = true
    webSettings.setEnableSmoothTransition(true)

    // 硬件加速配置
    if (Build.VERSION.SDK_INT >= 21) {
        webSettings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW // 使用常量替代魔法值0
        webView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
    } else if (Build.VERSION.SDK_INT >= 19) {
        webView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
    } else {
        webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
    }

    webView.webChromeClient = WebChromeClient()

    // Cookie配置(替换过时的CookieSyncManager)
    val cookieManager = CookieManager.getInstance()
    cookieManager.setAcceptCookie(true)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        cookieManager.setAcceptThirdPartyCookies(webView, true)
    }
    // 同步Cookie(API 21+使用flush,旧版本兼容处理)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        cookieManager.flush()
    } else {
        CookieSyncManager.createInstance(this).startSync()
    }

    // 设置WebViewClient,确保导航时正确携带Cookie
    webView.webViewClient = object : WebViewClient() {
        override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
            request?.url?.let { view?.loadUrl(it.toString()) }
            return true
        }
    }

    webView.loadUrl(url)
}

关键修改点说明

  • 统一缓存模式为LOAD_DEFAULT,避免缓存逻辑冲突;
  • 替换CookieSyncManager为推荐的CookieManager.flush()(针对API 21+),确保Cookie同步正常;
  • 移除废弃的savePassword设置,清理无效代码;
  • 添加自定义WebViewClient,确保页面跳转时请求上下文正确传递,保证Cookie携带完整;
  • 使用常量WebSettings.MIXED_CONTENT_ALWAYS_ALLOW替代魔法值0,提升代码可读性。

额外注意事项

如果后端使用Laravel等框架,需要确保WebView正确保存XSRF-TOKEN Cookie,并且在POST请求时自动携带X-XSRF-TOKEN请求头。可以通过注入JavaScript自动设置请求头,或者让后端在响应中正确配置Cookie的SameSite属性,确保WebView可以正常获取和使用CSRF令牌。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:44:51