Android Webview:脚本可能仅关闭由其打开的窗口 [英] Android Webview: Scripts may close only the windows that were opened by it

查看:576
本文介绍了Android Webview:脚本可能仅关闭由其打开的窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在加载特定的网址

例如.

webview.loadUrl("some.domain.com")

后记,我将其重定向到其他域,然后返回到我的域.然后,我尝试在我的JavaScript(window.close())中关闭窗口.在chrome开发人员工具上进行远程调试时,出现以下错误

Afterwords I am redirecting it to some other domain and then coming back to my domain. Then I try to close the window in my javascript (window.close()). I get the below error while debugging remotely on chrome developer tools

脚本只能关闭由它打开的窗口.

Scripts may close only the windows that were opened by it.

即使我与打开它的域相同,也遇到上述错误.

I am getting the above error even though I am on the same domain with which I opened it.

任何帮助将不胜感激.谢谢.

Any help would be very much appreciated. Thank you.

推荐答案

此答案将从Android App Developer的角度出发. 我希望它能对某人有所帮助.

This answer will be from Android App Developer perspective. I hope it will help someone.

问题对我来说非常相似:我正在通过webview打开一个网站,并且某些链接在新窗口中打开.问题是,webview不能与Web窗口一起使用.我的意思是,这是可能的,但是却没有达到预期的效果(以我为例,当从javascript角度在单独的窗口中打开链接时,该链接将覆盖先前打开的页面,并且无法用javascript中的window.close()来关闭该链接,最终导致前一页的状态丢失.

The problem was very similar for me: I was opening a web site via webview, and some of the links were opening in a new window. The thing is that webview cannot work with web windows out of the box. I mean, it can be possible, but not as expected (in my case, when a link was opened in a separate window from javascript perspective, it were overriding previously opened page, and cannot be closed with a window.close() from javascript, which eventually were causing a state loss on a previous page).

因此,在我的情况下,任务是在窗口中打开单个链接,然后返回上一页,而不会丢失任何状态.那是我的解决方案. 我有两个单独的WebView-一个作为主要的,另一个用于窗口中的链接. 为了能够对新窗口中的链接"事件做出反应,我将使用以下代码配置主webView:

So the task in my case was to open a single link in a window and go back to previous page without any state loss. That was my solution. I had two separate WebViews - one as a main one, and one for links in window. To be able to react on a "link in new window" event, I'll configured main webView with this code:

    webView.settings.javaScriptEnabled = true
    webView.settings.javaScriptCanOpenWindowsAutomatically = true
    webView.settings.setSupportMultipleWindows(true)

    webView.webChromeClient = object : WebChromeClient() {

    override fun onCreateWindow(view: WebView?, isDialog: Boolean, isUserGesture: Boolean,
                                resultMsg: Message?): Boolean {
        handleCreateWebWindowRequest(resultMsg)
        return true
    }
}

我们只需要onCreateWindow回调即可在主要的webView chrome客户端中进行覆盖,因为它只会打开新窗口.并且还允许webView.settings中的多窗口支持.当onCreateWindow回调触发时,请执行以下操作:

We need only onCreateWindow callback to override in main webView chrome client, since it will only open new windows. And also allow a multiwindow support in webView.settings. When an onCreateWindow callback triggers, do the following:

@SuppressLint("SetJavaScriptEnabled")
override fun handleCreateWebWindowRequest(resultMsg: Message?) {
    if (resultMsg == null) return
    if (resultMsg.obj != null && resultMsg.obj is WebView.WebViewTransport) 
        {
        val transport = resultMsg.obj as WebView.WebViewTransport
        windowWebView = WebView(this)
        windowWebView?.layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, 
        ViewGroup.LayoutParams.MATCH_PARENT)

        windowWebView?.settings?.javaScriptEnabled = true
        windowWebView?.settings?.javaScriptCanOpenWindowsAutomatically = true
        windowWebView?.settings?.setSupportMultipleWindows(true)
        windowWebView?.webViewClient = WebViewClient()
        windowWebView?.webChromeClient = object : WebChromeClient() {
            override fun onCloseWindow(window: WebView?) {
                super.onCloseWindow(window)
                handleCloseWebWindowRequest()
            }
        }

        container.addView(windowWebView)
        webView.visibility = View.GONE
        transport.webView = windowWebView
        resultMsg.sendToTarget()
    }
}

基本上,我们会将这个(创建窗口)请求发送到单独的webView.在其中,我们还应允许多窗口支持并附加chrome客户端,在此情况下,我们仅应侦听onCloseWindow事件,因为此webView应该充当窗口.当onCloseWindow触发时,我们只是关闭(隐藏/删除)应该作为窗口的webView,然后返回到主窗口.此处isWebWindowOpened方法调用仅检查windowWebView是否不为null且不可见.

Basically we're sending this (create window) request to a separate webView. In it we should also allow a multiwindow support and attach a chrome client, in wich we should listen only onCloseWindow event, since this webView should behave as a window. When onCloseWindow triggers, we're just closing (hiding/removing) webView that should act as a window, and returning to the main one. Here isWebWindowOpened method call just checks if the windowWebView is not null and visible.

private fun handleCloseWebWindowRequest() {
    if (!isWebWindowOpened()) return

    container.removeView(windowWebView)
    webView.visibility = View.VISIBLE
    windowWebView = null
}

我唯一能提到的是,当打开windowWebView时,onBackPressed操作应将其关闭,并调用handleCloseWebWindowRequest.

The only thing I can mention, is that when a windowWebView is opened, onBackPressed action should close it calling handleCloseWebWindowRequest.

这篇关于Android Webview:脚本可能仅关闭由其打开的窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆