Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/200.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何从远程页面访问phonegap API_Javascript_Android_Ios_Cordova_Cordova Plugins - Fatal编程技术网

Javascript 如何从远程页面访问phonegap API

Javascript 如何从远程页面访问phonegap API,javascript,android,ios,cordova,cordova-plugins,Javascript,Android,Ios,Cordova,Cordova Plugins,我必须面对以下情况: 我有一个已经存在的远程网页,我想开发一个应用程序,使用这个网页。 到目前为止,一切顺利。当我启动应用程序时,本地index.html会被加载,并将(window.open target:_self)重定向到外部网站。此网站在phonegap网络视图中打开。在外部网站上,我添加了cordova.js,以便访问本机phonegap API。但它不能正常工作。deviceReady事件已正确触发,但我无法访问phonegap API,例如navigator.camera 我如何才

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

我如何才能做到这一点,才能访问API

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


谢谢你的帮助

这是Cordova/PhoneGap强加的限制:


我过去曾禁用过此检查,以使Cordova能够处理非本地文件地址。

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

在我看来,您有一个本地网页(包括cordova脚本),然后从那里切换到远程网页(也包括脚本)。我不确定这个页面更改是否有效。如果成功,您可能需要等待第二个DeviceRady事件

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

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

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

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

我为phoneGap快速调试工作了很长一段时间,但在没有cordova.js与应用程序一起使用的情况下(不是在远程位置),我无法找到使API工作的方法

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

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


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

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

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


注意:您也可以在平台文件夹中找到特定于插件的文件,但这些文件不完整,因为它们缺少cordova.define(“…在开始时。这导致必需的模块未定义,因此只需进行构建并从那里获取它们。

好吧,对我来说,解决方案是多种来源的混合,但大多数解决方案都已找到。”

您应该做以下几点:

  • 定义
    config.xml
    以直接指向远程
    index.html

    <content src="http://your-remote-location/index.html" />
    
  • 在以下位置下找到
    SystemWebViewClient.java
    您的项目位置\platforms\android\CordovaLib\src\org\apache\cordova\engine

  • 在类顶部的private members部分添加以下枚举声明:

    private enum WebExtension {
        PNG, MP3, MP4, TTF, SVG, JS, ICO, HTML, CSS, EOT, WOFF, JSON;
    }
    
  • 找到
    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是应用程序以正确方式加载资源所必需的应用程序浏览器


    希望它能帮助别人。

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

    远程注入插件允许远程站点在加载到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>
    
    
    document.addEventListener(“deviceready”,函数(){
    编写(“现在你可以使用插件了”);
    },假);
    
    最简单的工作解决方案,允许从远程https页面加载本地文件,而不会出现混合内容错误:

    对于android:使用以下命令禁用混合内容策略:)

    对于ios:我向文件插件提交了一份PR,该文件插件解决了ios上的混合内容问题:apache/cordova插件文件#296固定版本可在以下位置获得:如果您在webview上加载远程站点,则它是
    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
        }
    }
    
    <html>
      <head>
      </head>
      <body>
        <script>
          document.addEventListener("deviceready", function() {
              document.write("Now you can use plugins"); 
          }, false);
        </script>
      </body>
    </html>