Android上的Chrome 61+导航被阻止错误

tho*_*aux 29 javascript redirect android google-chrome appauth

我正在构建一个登录页面,在提交和验证用户凭据后,它会打开一个本机移动应用程序.直到上周,我通过使用自定义方案URI实现了这个跨移动操作系统,如下所示:

function onLoginCallback() {
    const redirectUri = 'customscheme:/action?param1=val1&param2=val2';
    window.location.replace(redirectUri);
}
Run Code Online (Sandbox Code Playgroud)

登录页面显示在IABT中,是In App Browser选项卡的缩写.

但是,自从Chrome 61版本发布以来,这种方法在Android上被打破了.Chrome会阻止重定向,因为没有与重定向相关的明显用户操作(有关此问题的详细信息,请参阅此处).

因此,在执行上面的代码时,我最终会在控制台中发出警告:

导航被阻止:customscheme:/ action?param1 = val1¶m2 = val2

我也尝试将自定义方案网址更新为意图网址,但无济于事.谷歌搜索这个问题并不容易提供一个明确的解决方案,所以我希望有人可以帮助我.


编辑:尝试使用以下方案重现问题(尽可能接近现实生活场景):

  • IABT显示一个带有单个按钮的页面
  • 单击该按钮会将jsonp调用触发到模拟端点
  • 执行JSONP回调并触发自定义事件
  • 触发自定义事件的事件处理程序,并将浏览器重定向到另一个模拟端点
  • 该模拟端点以自定义深度链接方案的302响应.

唉,这似乎有效.我原本预计包含jsonp调用会导致Chrome阻止最终的重定向,因为它无法将其识别为用户启动的操作.


编辑2:管理以获得可重现的方案.我们已经设置了一个虚拟端点,根据请求只需302在Location头中返回一个自定义方案.除第一个尝试外,所有尝试都会阻止此操作.这个事实仍令人难以置信.我们正在使用AppAuth for Android应用程序来测试设置.

我正在打开端点的自定义选项卡,如下所示.代码来自这个答案.

void launchTab(Context context, Uri uri){
    final CustomTabsServiceConnection connection = new CustomTabsServiceConnection() {
        @Override
        public void onCustomTabsServiceConnected(ComponentName componentName, CustomTabsClient client) {
            final CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
            final CustomTabsIntent intent = builder.build();
            client.warmup(0L); // This prevents backgrounding after redirection
            intent.launchUrl(context, uri);
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    CustomTabsClient.bindCustomTabsService(context, "com.android.chrome", connection);
}
Run Code Online (Sandbox Code Playgroud)

tho*_*aux 1

我们最终使用经典的重定向后获取模式来实现登录和注册表单。

服务器使用302自定义 URI 方案进行响应。因为在此设置中,用户提交表单和接收重定向的浏览器之间没有异步执行,所以 Chrome 正确地将操作链识别为可信,因此不会阻止导航。

我意识到这可能不是每个人的首选解决方案。支持异步执行流的一种可能的替代方案是使用通用链接,因为它们使用常规的 http(s) 方案,Chrome 认为重定向(在发布我的问题时)不会有害。