如何从远程页面访问phonegap API

时间:2014-02-24 10:13:55

标签: javascript android ios cordova cordova-plugins

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

我如何完成它,才能访问API?

请不要评论它会被AppStore等拒绝

感谢您的帮助!

7 个答案:

答案 0 :(得分:12)

嗯,对我来说,解决方案是多个来源的混合,但大多数解决方案都被发现here

您应该做的是以下内容:

  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.javayour-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
        }
    }
    
  6. 所有资源请求的结果将是拦截每个资源请求,如果它包含**injection**字符串,它将减少资源位置并从本地设备位置请求它应用程序正在运行mimeType是应用浏览器以正确方式加载资源所必需的。

    希望它有所帮助。

答案 1 :(得分:9)

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

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

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

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

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

<access origin="http://your.website.fake" subdomains="true"/> 

答案 2 :(得分:9)

这个插件解决了这个问题,而无需自己编写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>

答案 3 :(得分:7)

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

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

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

答案 4 :(得分:0)

这是Cordova / PhoneGap强加的限制here

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

答案 5 :(得分:0)

我已经努力让它工作很长时间才能进行phoneGap快速调试,但是如果没有将cordova.js与应用程序(不在远程位置)一起使用,就无法找到使API工作的方法。 / p>

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

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

我不记得我实施和编程的确切方式,但如果我能找到它,我会编辑。

答案 6 :(得分:0)

最简单的工作解决方案,允许从远程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如果您加载远程站点在网络视图上https://example.com,然后它允许使用URL:https://example.com/cdvfile/bundle/www/cordova.js而不是cdvfile://localhost/bundle/www/cordova.js来访问本地文件,从而解决了混合内容问题