26

我必须以下情况:我有一个已经存在的远程网页,我想开发一个使用这个页面的应用程序。到目前为止,一切都很好。当我启动应用程序时,index.html会加载本地并将 ( window.open target: _self) 重定向到外部网站。该网站在 phonegap webview 中打开。在外部网站上,我添加了cordova.js以访问本机 phonegap API。但它不能正常工作。deviceReady事件被正确触发,但我无法访问 phonegap API,例如 navigator.camera。

我怎样才能完成它以访问 API?

请不要评论它将被AppStore等拒绝。

谢谢您的帮助!

4

7 回答 7

13

好吧,对我来说,解决方案是多种来源的混合,但大部分解决方案都在这里找到。

你应该做的是:

  1. 定义你config.xml的直接指向远程index.html

    <content src="http://your-remote-location/index.html" />
    
  2. 在您index.html对本地 android 设备资源的任何引用中添加一些唯一前缀,例如**injection**. 例如,cordova.js你会想出类似的东西:

    <script type="text/javascript" src="**injection**www/cordova.js"></script>
    
  3. SystemWebViewClient.java在以下位置找到: your-project-location\platforms\android\CordovaLib\src\org\apache\cordova\engine.

  4. 在顶部类的私有成员部分添加以下枚举声明:

    private enum WebExtension {
        PNG, MP3, MP4, TTF, SVG, JS, ICO, HTML, CSS, EOT, WOFF, JSON;
    }
    
  5. 找到该shouldInterceptRequest方法并在该try {行之后添加以下内容:

    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 是应用浏览器以正确方式加载资源所必需的。

希望它可以帮助某人。

于 2016-04-18T14:03:47.550 回答
11

在远程站点中包含cordova.js 脚本会很棘手,因为每个平台都有不同的cordova.js。您可以修改服务器,使其根据用户代理返回正确的 cordova.js,但这也很棘手,因为当您从移动浏览器查看站点时,它会包含此脚本,这是不可取的,因为 javascript 错误可能是显示给用户。从台式计算机查看站点时的情况相同,不应包含cordova.js。

在我看来,您有一个本地网页(包括科尔多瓦脚本),然后从那里切换到远程页面(也包括脚本)。我不确定此页面更改是否会起作用。如果它有效,您可能必须等待第二个 deviceready 事件。

但是您可以在 cordova 应用程序中将远程站点页面设置为根页面,不需要中间“加载器”页面。只需在 config.xml 文件中设置它:

<content src="http://your.website.fake/index.html" />

您需要确保允许在应用程序中加载您的网站。在同一个文件中,您应该添加:

<access origin="http://your.website.fake" subdomains="true"/> 
于 2014-05-21T11:15:48.593 回答
10

这个插件解决了这个问题,而无需自己编写一个 android 解决方案。

https://www.npmjs.com/package/cordova-plugin-remote-injection

https://github.com/TruckMovers/cordova-plugin-remote-injection

远程注入插件允许远程站点在加载到您的cordova 应用程序中时与cordova 的javascript API 交互。

  • 将 cordova 和安装的插件 JS 注入到任何远程浏览页面的 web 视图中,允许他们像打包的 cordova 应用程序一样访问 cordova 对象及其插件。

  • 支持 iOS 和 Android 平台。

我测试了它,它工作得很好。您唯一需要记住的是,您需要等待科尔多瓦准备就绪,如下所示:

<html>
  <head>
  </head>
  <body>
    <script>
      document.addEventListener("deviceready", function() {
          document.write("Now you can use plugins"); 
      }, false);
    </script>
  </body>
</html>
于 2017-01-16T15:23:51.297 回答
7

我也遇到过这个问题,在 config.xml(内容和访问标签)中更改内容不起作用。我在手机上运行时检查了该应用程序,发现当我加载远程站点时缺少一些文件。

首先是名为cordova_plugins.js的文件,您可以在平台文件夹中找到每个平台的文件。然后你还需要一些插件特定的文件。您可以通过构建并从那里提取它们来找到它们。对于 android,路径如下 APK/assets/www/plugins。只需复制服务器上的内容即可。

注意:您还可以在平台文件夹中找到插件特定文件,但它们不完整,因为它们缺少 cordova.define("... 开头。这导致必需模块未定义,所以只需构建并从那里得到它们。

于 2014-10-24T15:44:38.547 回答
0

这是 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 使用非本地文件地址。

于 2014-05-19T01:43:16.363 回答
0

我已经为 phoneGap 快速调试工作了很长时间,但是如果没有将 cordova.js 与应用程序一起使用(而不是在远程位置),我找不到使 API 工作的方法。

我不知道为什么这不起作用。如果你知道内部运作,我期待听到它......

我尝试的最后一件事是在主 html 中放置一个 100% x 100% iframe 并在同一个文档中加载本地 cordova.js。然后我能够使用 API,但在 iOS 上存在一些缩放问题,这是另一个问题......

我不记得我实现和构建它的确切方式,但如果我能找到它,我会进行编辑。

于 2014-05-22T19:02:25.743 回答
0

最简单的工作解决方案,允许从远程 https 页面加载本地文件而不会出现混合内容错误:

对于 android:禁用混合内容策略使用:https ://developer.android.com/reference/android/webkit/WebSettings.html#MIXED_CONTENT_ALWAYS_ALLOW )

对于 ios:我向解决 ios 上的混合内容问题的文件插件提交了 PR:apache/cordova-plugin-file#296 固定版本可在:https ://github.com/guylando/cordova-plugin-文件如果您在 webview 上加载远程站点https://example.com,则它允许使用 url 访问本地文件:https ://example.com/cdvfile/bundle/www/cordova.js 而不是 cdvfile:/ /localhost/bundle/www/cordova.js 并由此解决了混合内容问题

于 2019-03-03T22:44:14.713 回答