Cordova doesn't send origin on request in some Android devices

雨燕双飞 提交于 2019-12-03 02:54:21

We're experiencing the same issue. We first tried to implement a workaround where the App detects the Chrome version. The first time it sees version 76 it automatically restarts the app. Most users wouldn't even notice the restart. The workaround was based on several reports which stated, that the problem would only appear during the first run of the app after Chroe 76 had been installed and permanently disappear after a restart. However, it turned out, that the problem often returns seemingly randomly, so the woraround wasn't sufficient.

Luckily we're in control of the server side too, so we implemented a workaround there. Basicly we simply accept the file:// origin. The security impact of this workaround certainly depends on the individual application, so think about it carefully in case you consider implemeinting something similar.

In our case we're using ASP.NET where we were facing an additional challenge. Unfortunately EnableCorsAttribute fails when specifying file:// as an origin, which is in line with the CORS specification, which requires a hostname to be present in each origin (except when specifying *). So we finally came up with the following solution (specific to ASP.NET of course):

Create an ICorsPolicyProvider that overrides the validation logic in case of origin file:// and delegates to a nested provider (the original one) in all other cases:

    /// <summary>
    /// Object that allows clients with `file://` origin. This is used as a workaround
    /// for issues on Android devices running Chrome 76. See
    /// https://bugs.chromium.org/p/chromium/issues/detail?id=991107#c14
    /// 
    /// Simply adding `file://` to the allowed origins list doesn't work, because by
    /// specification a hostname is required.
    /// 
    /// This workaround should be removed as soon as Chrome 76 distribution has dropped
    /// sufficiently.
    /// </summary>
    // TODO: Remove this workaround once Chrome 76 is not around anymore.
    public class CorsPolicyProviderAcceptingFileOrigin : ICorsPolicyProvider
    {
        public readonly ICorsPolicyProvider inner;

        public CorsPolicyProviderAcceptingFileOrigin(ICorsPolicyProvider inner)
        {
            this.inner = inner;
        }

        public async Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (
                request.Headers.TryGetValues("origin", out IEnumerable<string> origins)
                && origins.SequenceEqual(new[] { "file://" })
                )
            {
                var policy = new CorsPolicy()
                {
                    AllowAnyHeader = true,
                    AllowAnyMethod = true,
                    AllowAnyOrigin = false,
                };
                policy.Origins.Add("file://");

                return policy;
            }

            return await this.inner.GetCorsPolicyAsync(request, cancellationToken);
        }
    }

and then use it like this in WebApiConfig.cs:

// get the original EnableCorsAttribute
ICorsPolicyProvider cors = ...;

// this is a workaround for Android devices running Chrome 76 and should be removed in future versions.
// See https://bugs.chromium.org/p/chromium/issues/detail?id=991107
cors = new CorsPolicyProviderAcceptingFileOrigin(cors);

config.EnableCors(cors);

This is an open bug on Chromium webview interesting the 76 version; in this specific version the OOR-CORS remains enabled in the first run.

https://bugs.chromium.org/p/chromium/issues/detail?id=991107#c14

A change list will be merged to the 76 branch directly.

We're experiencing the same issue... AJAX calls won't work after the first coldstart in our Cordova projects. If we restart the app (remove app from background) then it works... It appears to be a problem with the Chromium WebView version... I found a very ugly workaround. Use the

https://github.com/dpa99c/cordova-diagnostic-plugin#restart

plugin and restart the app after the first coldstart. Check in localStorage for a coldstart flag. If you don't find it restart the app.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!