我有一个cordova(2.7.0)安卓应用程序,当它尝试加载iframe,其中源具有协议相对(网络路径引用)src时,会因应用程序错误而崩溃。
例如,如果iframe是:
<iframe src="//instagram.com/p/beGdCuhQYl/embed/?wmode=opaque&wmode=opaque" width="800" height="928" style="border:0;" frameborder="0"></iframe>
然后该应用尝试从
加载来源file://instagram.com/p/beGdCuhQYl/embed/?wmode=opaque&wmode=opaque
由于加载此iframe的html页面是从文件系统加载的,因此它正在执行此操作。但是,有没有办法阻止应用程序崩溃? iOS上的同一个cordova应用程序只是不加载任何东西,并且有一个空白的iframe。如果Android应用程序的行为方式相同,我会很高兴。
如果有一种方法可以告诉cordova应用程序从http://而不是file://加载这些类型的网址,那会更好。但我认为这要求太多。
答案 0 :(得分:2)
好的,所以我最终分两部分来完成。第一部分,尝试在javascript中尽可能多地修复协议相对URL,第二部分是提供一些java代码来忽略我错过的任何内容。
第一部分(使用jQuery)
/**
* 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;
}
答案 1 :(得分:0)
Cordova不支持协议相对src,它希望您指定文件或http。