Reputation: 6069
I have a website that I want to enhance on mobiles with a hybrid app. Ideally the app would load the remote site over http but load the platform specific code locally. I've tried to set up a Cordova project to do this but am having lots of trouble. Cordova 4.3.1, Cordova Android 3.7.2 on a Nexus 7 Android 4.4.4 has been my environment. (The google maps plugin is for Cordova Android < 4.)
If I try to load file:///android_assets/www/cordova.js from an http site, chromium says Not allowed to load local resource
. I tried to set up a local URL scheme but don't know what android-specific code to put where.
Is this the right way to make a hybrid app? Is there a cordova plugin to allow loading file: from http:?
I also tried using an iframe and passing messages to indicate cordova is enabled and which plugins are installed, but I don't want to deal with having the http server re-serve the same js files that are already available locally.
I also thought to download the website and access it over file: but I imagine I will have the same problem trying to access http resources.
Upvotes: 1
Views: 4714
Reputation: 163
The cdvfile solution will not work for active content (js files) because of the mixed content policy. Here is how to make it work:
For android: Disable mixed content policy by putting the following code inside the pluginInitialize method of your cordova plugin:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
final WebSettings settings = ((WebView)this.webView.getView()).getSettings();
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
https://developer.android.com/reference/android/webkit/WebSettings.html#MIXED_CONTENT_ALWAYS_ALLOW)
Then include local cordova.js using:
<script src="cdvfile://localhost/assets/www/cordova.js"></script>
For ios: I submitted a PR to the file plugin which solves the mixed content problem on ios: apache/cordova-plugin-file#296 The fixed version is available at: https://github.com/guylando/cordova-plugin-file If you load a remote site https://example.com on the webview then it allows to access local files using the url: https://example.com/cdvfile/bundle/www/cordova.js instead of cdvfile://localhost/bundle/www/cordova.js And by this solves the mixed content problems
Include local cordova.js using:
<script src="/cdvfile/bundle/www/cordova.js"></script>
Upvotes: -1
Reputation: 161
I am able to load local cordova.js
on remote html using cordova-plugin-file (cdvfile://
) plugin .
Add cordova-plugin-file plugin to your cordova project https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/
Confirm cdvfile URI for cordova.js
using below sample code(Android example)
checkCordovaJSPath('file:///android_asset/www/cordova.js');
function checkCordovaJSPath(jsUri) {
window.resolveLocalFileSystemURL(jsUri, function success(fileEntry){
console.log("got cordova.js file: " + fileEntry.fullPath);
console.log('cordova.js cdvfile URI: ' + fileEntry.toInternalURL());
});
}
cordova.js
using cdvfile://localhost
on remote html.<script type="text/javascript" src="cdvfile://localhost/assets/www/cordova.js"/>
Upvotes: 7
Reputation: 6069
I don't know if this is the right way to make a hybrid app, but I got it working by serving assets over http with https://github.com/floatinghotpot/cordova-httpd .
On the local page bundled with the app I have added:
<script type="text/javascript">
document.addEventListener("deviceready", function () {
var httpd = cordova.plugins.CorHttpd;
httpd.startServer({
'www_root': '',
'port': 8080,
'localhost_only': false
}, function (url) {
// if server is up, it will return the url of http://<server ip>:port/
// the ip is the active network connection
// if no wifi or no cell, "127.0.0.1" will be returned.
document.getElementById('url').innerHTML = "server is started: <a href='" + url + "' target='_blank'>" + url + "</a>";
location.replace('http://192.168.0.134:9090/homechooser/beta/#' + JSON.stringify({'cordova.js': url + '/cordova.js'}));
}, function (error) {
document.getElementById('url').innerHTML = 'failed to start server: ' + error;
});
}, false);
</script>
<div id="url"></div>
Then on the remote webpage I have added:
(function () {
var hash;
if (location && location.hash)
try {
hash = JSON.parse(location.hash.substring(1));
} catch (e) {
}
if (hash && hash['cordova.js'])
$.getScript(hash['cordova.js'], function () {
alert("Running cordova.js");
});
})();
now to see if cordova can actually be used this way...
Upvotes: 1
Reputation: 15336
Thing is your are trying to load a web-url on the local hosted app, imagine doing the same thing on Native Android App, what would you do? you will place a web-client or a web-browser in your app. But Cordova/Phonegap already uses Web-Browser to render your pages. So its like a using web-browser inside a web browser.
You need to install InAppBrowser which will give you the ability to load 3rd party hosted web pages.
Sample Code
document.addEventListener("deviceready", onDeviceReady, false);
// device APIs are available
//
function onDeviceReady() {
var ref = window.open('http://yourWebPage.com', '_blank', 'location=yes');
ref.addEventListener('loadstart', function(event) { alert('start: ' + event.url); });
ref.addEventListener('loadstop', function(event) { alert('stop: ' + event.url); });
ref.addEventListener('loaderror', function(event) { alert('error: ' + event.message); });
ref.addEventListener('exit', function(event) { alert(event.type); });
}
Upvotes: -1