Android Cordova/Phonegap应用程序上的应用程序错误

Android Cordova/Phonegap应用程序上的应用程序错误,android,cordova,cordova-2.0.0,Android,Cordova,Cordova 2.0.0,我有一个cordova(2.7.0)android应用程序,当它试图加载源具有协议相关(网络路径引用)src的iframe时,由于应用程序错误而崩溃 例如,如果iframe是: <iframe src="//instagram.com/p/beGdCuhQYl/embed/?wmode=opaque&amp;wmode=opaque" width="800" height="928" style="border:0;" frameborder="0"></iframe&

我有一个cordova(2.7.0)android应用程序,当它试图加载源具有协议相关(网络路径引用)src的iframe时,由于应用程序错误而崩溃

例如,如果iframe是:

<iframe src="//instagram.com/p/beGdCuhQYl/embed/?wmode=opaque&amp;wmode=opaque" width="800" height="928" style="border:0;" frameborder="0"></iframe>
因为加载这个iframe的html页面是从文件系统加载的,所以这样做是有意义的。但是,有没有办法阻止应用程序崩溃?iOS上的同一个cordova应用程序没有加载任何内容,并且有一个空白的iframe。如果android应用程序的表现也一样,我会很高兴


如果有一种方法可以告诉cordova应用程序从http://而不是从file://加载这些类型的URL,那就更好了,但我认为这要求太高了。

cordova不支持协议相关的src,它希望您指定file或http

好的,我最后分两部分来做。第一部分,尝试在javascript中修复尽可能多的协议相关URL,第二部分是提供一些java代码来忽略我遗漏的任何内容

第一部分(使用jQuery)

/**
*获取文本,查找具有以下src属性的元素:
*协议相对(//),并将其转换为http(http://)
*@param{String}text要在其中修复URL的文本
*@返回{String}带有更正URL的更新文本
*/
FixProtocolRelativeUrlContext:函数(文本){
var$html$elements;
试一试{
$html=$(''+文本+'');
$elements=$html.find('[src^=“/”]);
if($elements.length){
$elements.each(函数(){
var$this=$(this);
$this.attr('src','http:'+$this.attr('src');
});
返回$html.html();
}否则{
返回文本;
}
}捕获(ex){
返回文本;
}
},
第二部分:

/**
 * Override the default makeWebViewClient and provide a custom handler for protocol
 * relative urls.
 */
@Override
public CordovaWebViewClient makeWebViewClient(CordovaWebView webView) {
    //
    // We already try to fix protocol relative urls in the javascript. But this is a safety net in case anything
    // gets through. So, in order to not crash the app, lets handle these types ourself and just swallow them up
    // for now. The url won't load but at least it won't crash the app either. By the time the protocol relative
    // url gets in here, it has the file: appended to it already. If it was a true file:// path to something on the
    // device, then it will have file:///some/path, and if it was a protocol relative url that was converted to a
    // file:// then it will have file://some.domain, so we look for urls that don't have the three /'s
    //
    final Pattern pattern = Pattern.compile("^file://[^/].*$");

    CordovaWebViewClient webViewClient;

    if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) {
        webViewClient = new CordovaWebViewClient(this, webView) {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Matcher matcher = pattern.matcher(url);
                if (matcher.matches()) {
                    Log.i(LOG_TAG, "swallowing url '" + url + "'");
                    return true;
                } else {
                    return super.shouldOverrideUrlLoading(view, url);
                }
            }
        };
    } else {
        webViewClient = new IceCreamCordovaWebViewClient(this, webView) {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Matcher matcher = pattern.matcher(url);
                if (matcher.matches()) {
                    Log.i(LOG_TAG, "swallowing url '" + url + "'");
                    return true;
                } else {
                    return super.shouldOverrideUrlLoading(view, url);
                }
            }
        };
    }

    return webViewClient;
}
/**
*覆盖默认的makeWebViewClient并为协议提供自定义处理程序
*相对URL。
*/
@凌驾
公共CordovaWebViewClient makeWebViewClient(CordovaWebView webView){
//
//我们已经尝试在javascript中修复协议相关的URL,但这是一个安全网,以防出现任何问题
//所以,为了不让应用程序崩溃,让我们自己来处理这些类型的应用程序,然后把它们吞下去
//目前,url不会加载,但至少不会使应用程序崩溃
//url在这里,它已经附加了一个文件:如果它是一个真实的文件://指向
//设备,那么它将具有file:///some/path,如果它是转换为
//文件://那么它将具有file://some.domain,因此,我们查找没有三个/的URL
//
最终模式=模式。编译(“^file://[^/].*$”;
CordovaWebViewClient-webViewClient;
if(android.os.Build.VERSION.SDK_INT
能否将iframe src改为“http://”而不是“/”?我可能会做一些字符串替换客户端,但这有点难看。URL来自第三方,因此我们无法控制它们。也许这可以解决您的问题:感谢您确认我们做了一些“正确”的事情。但我得说实话,这种情况糟透了。有问题的内容没有从我们的系统中出来,因此,由于这个聪明的想法(protocoless URL),我们的应用程序完全崩溃了。绿巨人粉碎!!
/**
 * Takes text, looks for elements with src attributes that are
 * protocol relative (//) and converts them to http (http://)
 * @param {String} text the text that you want to fix urls in
 * @returns {String} the updated text with corrected urls
 */
fixProtocolRelativeUrlsInText: function(text) {
    var $html, $elements;
    try {
        $html = $('<div>' + text + '</div>');
        $elements = $html.find('[src^="//"]');

        if ($elements.length) {
            $elements.each(function() {
                var $this = $(this);
                $this.attr('src', 'http:' + $this.attr('src'));
            });
            return $html.html();
        } else {
            return text;
        }
    } catch(ex) {
        return text;
    }
},
/**
 * Override the default makeWebViewClient and provide a custom handler for protocol
 * relative urls.
 */
@Override
public CordovaWebViewClient makeWebViewClient(CordovaWebView webView) {
    //
    // We already try to fix protocol relative urls in the javascript. But this is a safety net in case anything
    // gets through. So, in order to not crash the app, lets handle these types ourself and just swallow them up
    // for now. The url won't load but at least it won't crash the app either. By the time the protocol relative
    // url gets in here, it has the file: appended to it already. If it was a true file:// path to something on the
    // device, then it will have file:///some/path, and if it was a protocol relative url that was converted to a
    // file:// then it will have file://some.domain, so we look for urls that don't have the three /'s
    //
    final Pattern pattern = Pattern.compile("^file://[^/].*$");

    CordovaWebViewClient webViewClient;

    if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) {
        webViewClient = new CordovaWebViewClient(this, webView) {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Matcher matcher = pattern.matcher(url);
                if (matcher.matches()) {
                    Log.i(LOG_TAG, "swallowing url '" + url + "'");
                    return true;
                } else {
                    return super.shouldOverrideUrlLoading(view, url);
                }
            }
        };
    } else {
        webViewClient = new IceCreamCordovaWebViewClient(this, webView) {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Matcher matcher = pattern.matcher(url);
                if (matcher.matches()) {
                    Log.i(LOG_TAG, "swallowing url '" + url + "'");
                    return true;
                } else {
                    return super.shouldOverrideUrlLoading(view, url);
                }
            }
        };
    }

    return webViewClient;
}