【问题标题】:Hybrid app with remote html and local cordova.js具有远程 html 和本地 cordova.js 的混合应用程序
【发布时间】:2015-06-24 04:16:53
【问题描述】:

我有一个网站,我想通过混合应用在手机上进行增强。理想情况下,该应用程序将通过 http 加载远程站点,但在本地加载特定于平台的代码。我试图建立一个 Cordova 项目来做到这一点,但遇到了很多麻烦。 Nexus 7 Android 4.4.4 上的 Cordova 4.3.1、Cordova Android 3.7.2 一直是我的环境。 (谷歌地图插件适用于 Cordova Android

如果我尝试从 http 站点加载 file:///android_assets/www/cordova.js,chromium 会显示 Not allowed to load local resource。我尝试设置一个本地 URL 方案,但不知道将什么特定于 android 的代码放在哪里。

这是制作混合应用的正确方法吗?是否有允许从 http: 加载文件的 cordova 插件?


我还尝试使用 iframe 并传递消息以指示 cordova 已启用以及安装了哪些插件,但我不想处理让 http 服务器重新提供本地已经可用的相同 js 文件的问题。

我也想过下载网站并通过文件访问它:但我想我在尝试访问 http 资源时会遇到同样的问题。

【问题讨论】:

标签: android cordova


【解决方案1】:

我可以使用 cordova-plugin-file (cdvfile://) 插件在远程 html 上加载本地 cordova.js

  1. 将 cordova-plugin-file 插件添加到您的 cordova 项目 https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/

  2. 使用以下示例代码确认cordova.js 的cdvfile URI(Android 示例)

    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());
               
    });
    }
  1. 在远程 html 上使用 cdvfile://localhost 加载 cordova.js

<script type="text/javascript" src="cdvfile://localhost/assets/www/cordova.js"/>

【讨论】:

    【解决方案2】:

    我不知道这是否是制作混合应用程序的正确方法,但我通过使用 https://github.com/floatinghotpot/cordova-httpd 的 http 服务资产来实现它。

    在与我添加的应用程序捆绑在一起的本地页面上:

        <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>
    

    然后在我添加的远程网页上:

    (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");
            });
    })();
    

    现在看看cordova是否真的可以这样使用......

    【讨论】:

    【解决方案3】:

    由于混合内容政策,cdvfile 解决方案不适用于活动内容(js 文件)。以下是如何使其工作:

    对于 android:通过将以下代码放入您的 cordova 插件的 pluginInitialize 方法中来禁用混合内容策略:

    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)

    然后使用以下方法包含本地cordova.js:

    <script src="cdvfile://localhost/assets/www/cordova.js"></script>
    

    对于 ios:我提交了一个解决 ios 上混合内容问题的文件插件的 PR:apache/cordova-plugin-file#296 修复版本在:https://github.com/guylando/cordova-plugin-file 如果你加载远程站点 @987654323 @ 在 webview 然后它允许使用 url 访问本地文件:https://example.com/cdvfile/bundle/www/cordova.js 而不是 cdvfile://localhost/bundle/www/cordova.js 并且通过这解决了混合内容问题

    使用以下方法包含本地cordova.js:

    <script src="/cdvfile/bundle/www/cordova.js"></script>
    

    【讨论】:

    • 与 pramoda 的回答相比,您的解决方案很难遵循。请参阅回答指南:stackoverflow.com/help/how-to-answer,尤其是“始终引用重要链接中最相关的部分,以防目标站点无法访问或永久离线。”
    • 你能详细说明“你的科尔多瓦插件”吗?我正在编写一个 Cordova 应用程序,而不是插件。
    • 我个人的结论是,cordova 并不总是有适用于所有东西的插件,插件环境是由极少数人构建的,这些人大多多年来没有更新他们的存储库。如果您想使用最新的 android/ios 功能,您别无选择,只能添加自己的插件,在该插件中,您将能够为您想要的所有功能插入任何 ios 和 android 代码,这些功能在其他插件中不可用。
    • 这也有很大的性能优势,因为为每件小事添加新插件会使应用程序性能变慢,因为每个插件都需要在应用程序启动时加载其 javascript 文件。
    • 普通插件添加命令中将npm包名替换为github仓库的url
    【解决方案4】:

    问题是您正在尝试在本地托管应用程序上加载 web-url,想象在 Native Android App 上做同样的事情,您会怎么做?您将在您的应用程序中放置一个网络客户端或网络浏览器。但是 Cordova/Phonegap 已经使用 Web-Browser 来呈现您的页面。所以它就像在网络浏览器中使用网络浏览器。

    您需要安装 InAppBrowser,这将使您能够加载第三方托管的网页。

    示例代码

      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); });
        }
    

    【讨论】:

    • 但这不允许yourWebPage.com使用cordova.js
    • 哦,但这让我想到了使用ref.executeScript(details, callback);yourWebPage.com 中加载cordova.js。会尝试并告诉你。
    • 本意是这样。如果您使用 google.com 代替 yourWebPage.com 那么为什么 Google.com 允许您的 js 在他的网页上运行?
    • executeScript 在浏览器本地注入脚本,而不是在网页中。
    • 我不想使用google.com。我想使用yourWebPage.com,我希望它访问cordova.js。我允许cordova.js 在我的网页上运行,因为我信任它。铬以另一种方式提供安全性。它不允许访问file:,因为它不信任http:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    相关资源
    最近更新 更多