Android Webview XHR 请求新 cookie 未保留

Android Webview XHR request new cookie not persisted

我有一个 Xamarin.Forms 5.0 应用程序(适用于 iOS 和 Android)。我不确定这是 Xamarin 问题还是只是 Android。在 iOS 上工作正常。

在应用程序中,我使用 webview 来显示单页 web 应用程序。在那个水疗中心内,我有一个带有“记住我”复选框的登录页面。选中此项时,后端会创建持久性 cookie 而不是 sessioncookie。登录是通过向后端发出 XHR 请求完成的。

似乎一切正常,但当应用程序重新启动时,它不再知道 cookie,用户必须重新登录。 当我在 webview 中完全重新加载页面时(登录后),cookie 似乎已保留。重启应用程序后,用户自动登录,因此cookie可用。

所以问题似乎是 XHR 请求响应中的新 cookie 没有持久化,而正常页面请求的响应 cookie 是。

有人对此有任何想法吗?

添加了一些代码

我用 Android 应用程序创建了一个简单的 Xamarin.Forms 项目。 在 MainPage.xaml 中添加了这个:

    <StackLayout>
        <Button Clicked="Button_Clicked" Text="(Re)Load"></Button>
        <WebView x:Name="wv"
                 WidthRequest="1000" 
                 HeightRequest="1000"
            ></WebView>
    </StackLayout>

在代码隐藏中:

        private void Button_Clicked(object sender, EventArgs e)
        {
            wv.Source = "https://---.---.nl/portal";
        }

这将加载一个 SPA 网络应用程序。显示的代码不多。

据我所知,UWP 和 iOS 会在 WebView 和本机 http 客户端之间自动共享它们的 cookie 容器,但是 Android 不会。

WebView 可以使用 CookieManager 来处理 cookie。如果您想在两者之间共享 cookie,您将不得不手动处理信息。您需要知道这些 cookie 的域的 Uri。

private void CopyCookies(HttpResponseMessage result, Uri uri)
{
foreach (var header in result.Headers)
    if (header.Key.ToLower() == "set-cookie")
        foreach (var value in header.Value)
             _cookieManager.SetCookie($"{uri.Scheme}://{uri.Host}", value);

foreach (var cookie in GetAllCookies(_cookieContainer))
    _cookieManager.SetCookie(cookie.Domain, cookie.ToString());
}

 public void ReverseCopyCookies(Uri uri)
{
var cookie = _cookieManager.GetCookie($"{uri.Scheme}://{uri.Host}");

if (!string.IsNullOrEmpty(cookie))
    _cookieContainer.SetCookies(new Uri($"{uri.Scheme}://{uri.Host}"), cookie);
}

不太清楚,至少对我而言,WebView 何时刷新 cookie,何时不刷新。 对我来说,简单的解决方案是每次调用包含 webview 的 activity 的 onPause 生命周期事件时刷新 cookie。当另一个 activity 启动时,或者用户切换到另一个应用程序或关闭该应用程序时,就会发生这种情况。

    protected override void OnPause()
    {
        base.OnPause();
        Android.Webkit.CookieManager.Instance.Flush();
    }