index.html
被加载并重定向(window.open target: _self
)到外部网站。这个网站在phonegap webview中打开。在外部网站上,我添加了cordova.js
以便访问本机phonegap API。但它没有正确工作。 deviceReady 事件被正确触发,但我无法访问phonegap API,例如navigator.camera。我该如何才能访问API呢?
请不要评论说它会被AppStore等拒绝。
感谢您的帮助!
index.html
被加载并重定向(window.open target: _self
)到外部网站。这个网站在phonegap webview中打开。在外部网站上,我添加了cordova.js
以便访问本机phonegap API。但它没有正确工作。 deviceReady 事件被正确触发,但我无法访问phonegap API,例如navigator.camera。对我而言,解决方案源于多个渠道,但其中大部分在这里找到了。
你应该执行以下步骤:
Define your config.xml
to point directly to the remote index.html
.
<content src="http://your-remote-location/index.html" />
In your index.html
any reference to a local android device resource prepend with some unique prefix like **injection**
. For instance for cordova.js
you'll come up with something like:
<script type="text/javascript" src="**injection**www/cordova.js"></script>
Find SystemWebViewClient.java
under the following location: your-project-location\platforms\android\CordovaLib\src\org\apache\cordova\engine
.
Add the following enum declaration in the private members section of the class at the top:
private enum WebExtension {
PNG, MP3, MP4, TTF, SVG, JS, ICO, HTML, CSS, EOT, WOFF, JSON;
}
Locate the shouldInterceptRequest
method and add the following right after the try {
line:
if(url != null && url.contains(INJECTION_TOKEN)) {
String assetPath = url.substring(url.indexOf(INJECTION_TOKEN) + INJECTION_TOKEN.length(), url.length());
try {
String mimeType = "text/plain";
String ext = assetPath.substring(assetPath.lastIndexOf(".") + 1, assetPath.length());
WebExtension extension = WebExtension.valueOf(ext.toUpperCase());
switch(extension) {
case PNG:
mimeType = "image/png";
break;
case MP3:
mimeType = "audio/mpeg";
break;
case MP4:
mimeType = "video/mp4";
break;
case TTF:
mimeType = "application/x-font-ttf";
break;
case SVG:
mimeType = "image/svg+xml";
break;
case JS:
mimeType = "application/javascript";
break;
case ICO:
mimeType = "image/x-icon";
break;
case HTML:
mimeType = "text/html";
break;
case CSS:
mimeType = "text/css";
break;
case EOT:
mimeType = "application/vnd.ms-fontobject";
break;
case WOFF:
mimeType = "application/x-font-woff";
break;
case JSON:
mimeType = "application/json";
break;
}
WebResourceResponse response = new WebResourceResponse(
mimeType,
"UTF-8",
parentEngine.webView.getContext().getAssets().open(assetPath)
);
return response;
} catch (IOException e) {
e.printStackTrace(); // Failed to load asset file
}
}
所有这一切的结果将是拦截每个资源请求,并在其中包含**injection**
字符串的情况下,削减资源位置,并从应用程序运行的本地设备位置请求它。mimeType是通过应用程序浏览器以正确的方式加载资源所必需的。
希望对某些人有所帮助。
<content src="http://your.website.fake/index.html" />
你需要确保允许在应用程序中加载你的网站。在同一文件中,你应该添加:<access origin="http://your.website.fake" subdomains="true"/>
这个插件可以解决问题,不需要自己编写Android解决方案。
https://www.npmjs.com/package/cordova-plugin-remote-injection
https://github.com/TruckMovers/cordova-plugin-remote-injection
远程注入插件允许远程网站在加载到您的 Cordova 应用程序中时与 Cordova 的 JavaScript API 进行交互。
将 Cordova 和已安装插件 JS 注入到 WebView 中,以便任何远程浏览页面都可以像打包的 Cordova 应用一样访问 Cordova 对象及其插件。
支持 iOS 和 Android 平台。
我测试了它,它运行良好。唯一需要记住的是,您需要等待 cordova 准备就绪,像这样:
<html>
<head>
</head>
<body>
<script>
document.addEventListener("deviceready", function() {
document.write("Now you can use plugins");
}, false);
</script>
</body>
</html>
这是 Cordova/PhoneGap 强制限制 在这里:
if (startFilePath == nil) {
loadErr = [NSString stringWithFormat:@"ERROR: Start Page at '%@/%@' was not found.", self.wwwFolderName, self.startPage];
NSLog(@"%@", loadErr);
self.loadFromString = YES;
appURL = nil;
}
我过去曾禁用此检查,以便让Cordova与非本地文件地址一起使用。
我已经花了很长时间来解决PhoneGap快速调试的问题,但是没有找到一种在没有将cordova.js与应用程序(不是在远程位置)放在一起的情况下使API工作的方法。
我不确定为什么这样不起作用。如果你知道内部运作方式,我期待听到你的意见...
我最后尝试的方法是在主HTML中放置一个100% x 100%的iframe,并在同一文档中加载本地的cordova.js。然后,我能够使用API,但在iOS上存在一些缩放问题,这是另一个问题...
我不记得我实现和构造这个的确切方式,但如果我找到了,我会进行编辑。
最简单的解决方案,允许从远程https页面加载本地文件而不会出现混合内容错误:
对于Android:使用以下方法禁用混合内容策略:https://developer.android.com/reference/android/webkit/WebSettings.html#MIXED_CONTENT_ALWAYS_ALLOW)
对于iOS:我向文件插件提交了一个PR,解决了iOS上的混合内容问题:apache/cordova-plugin-file#296 修复版本可在此处获取:https://github.com/guylando/cordova-plugin-file 如果您在Webview上加载远程站点 https://example.com,则可以使用URL https://example.com/cdvfile/bundle/www/cordova.js 而不是 cdvfile://localhost/bundle/www/cordova.js 来访问本地文件,并通过此方式解决混合内容问题。
window.location="http://your.website";
和<content src="http://your.website"" />
遇到相同的问题。 - MichaelS