Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.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
Android WebView(Xamarin)中的VueJS_Android_Vue.js_Xamarin_Webview - Fatal编程技术网

Android WebView(Xamarin)中的VueJS

Android WebView(Xamarin)中的VueJS,android,vue.js,xamarin,webview,Android,Vue.js,Xamarin,Webview,我正在尝试将一个使用VueJS开发的小型混合C#/单页应用程序捆绑为android应用程序。我们有一些类,它们创建和镜像并将其发送到ESC打印机。如果我们从服务器加载应用程序,一切正常: theView.LoadUrl(“https://our-app.our-server.com" ); 但是当我们从file:///android_asset/index.html 它开始了,但是页面是空的 我在chrome调试器中看到VueJS成功创建了一些元素: 控制台中没有错误,只是一个空屏幕 我错

我正在尝试将一个使用VueJS开发的小型混合C#/单页应用程序捆绑为android应用程序。我们有一些类,它们创建和镜像并将其发送到ESC打印机。如果我们从服务器加载应用程序,一切正常:

theView.LoadUrl(“https://our-app.our-server.com" );
但是当我们从file:///android_asset/index.html 它开始了,但是页面是空的

我在chrome调试器中看到VueJS成功创建了一些元素:


控制台中没有错误,只是一个空屏幕


我错过了什么

在index.html中,尝试去掉css和js链接开头的“/”

i、 e.改变:

<script src=/js/chunk-vendors.19bfdd07.js></script>
<script src=/js/app.d04362c5.js></script>
而不是:

file:///android_asset/js/chunk-vendors.19bfdd07.js
file:///android_asset/js/app.d04362c5.js

您可以将vue.config.js配置为不输出斜杠

经过一段时间的挣扎之后,我的问题的根源似乎是在构建中,为js文件和资产生成了绝对路径。我更改了vue.config.js中的两个设置以使其正常工作

请注意,前面的解决方案也可以,但它隐藏了真正的问题,而不是解决它。此外,该解决方案仅适用于android(我没有发现如何在iOS上实现同样的功能)

下面是我所做的:我将assetsDir和publicPath更改为空字符串,以强制构建生成相对路径

    module.exports = {
      assetsDir: '',
      publicPath: '',
      .....
    }
此外,我还必须关闭路由器的历史模式,并定义一条额外的路由:

    {
      path: '/index.html',
      name: 'index',
      component: ..........,
    }
这样,iOS上的文件系统也不会出现问题

-------------------替代解决方案---------------------

以下解决方案仅适用于android:

我想出来了。这是文件://URL!改为http://localhost 它可以工作(+几行代码)

同样的原因,当您直接从文件系统打开某些页面时,为什么这些页面无法工作。我记得,为了查看某些网页,我必须创建一个本地web服务器,否则我几乎看不到任何东西,因为以这种方式打开网页时,浏览器的限制更大。有一次我把它改成了http://localhost 并修正了我的“应接受请求”以满足“任何请求”http://localhost“从安卓的资产和一切工作

还不确定原因-我必须以这种方式加载索引:

wv.LoadDataWithBaseURL( "http://localhost", new StreamReader( Assets.Open( "index.html" ) ).ReadToEnd(), "text/html", "UTF-8", null );
而不是

wv.LoadUrl( "http://localhost/index.html" );
此外,我还必须覆盖WebViewClient,以便在需要时提供来自资产的内容http://localhost 请求:


    // view client to serve the web from assets folder correctly
    public class MyWebViewClient : WebViewClient {

        private AssetManager m_Assets;

        public MyWebViewClient( AssetManager assets ) {
            m_Assets = assets;
        }

        public static string GetMimeType( String url ) {
            String type = null;
            String extension = url.Split( '.' ).Last();
            if ( extension != null ) {
                if ( extension == "css" ) {
                    return "text/css";
                } else if ( extension == "js" ) {
                    return "text/javascript";
                } else if ( extension == "png" ) {
                    return "image/png";
                } else if ( extension == "gif" ) {
                    return "image/gif";
                } else if ( extension == "jpg" ) {
                    return "image/jpeg";
                } else if ( extension == "jpeg" ) {
                    return "image/jpeg";
                } else if ( extension == "woff" ) {
                    return "application/font-woff";
                } else if ( extension == "woff2" ) {
                    return "application/font-woff2";
                } else if ( extension == "ttf" ) {
                    return "application/x-font-ttf";
                } else if ( extension == "eot" ) {
                    return "application/vnd.ms-fontobject";
                } else if ( extension == "svg" ) {
                    return "image/svg+xml";
                }

                type = "text/html";
            }

            return type;
        }

        public override WebResourceResponse ShouldInterceptRequest( WebView view, IWebResourceRequest request ) {

            if ( request.Url != null && request.Url.Path != null && request.Url.Host == "localhost" ) {
                var mimeType = GetMimeType( request.Url.Path );
                var fileUrl = request.Url.Path
                    .Replace( "file://", "" )
                    .Replace( "android_asset/", "" )
                    .Trim( '/' );

                string extension = request.Url.Path.Split( '.' ).Last();;
                string fileEncoding = "application/octet-stream";
                if ( extension.EndsWith( "html" ) || extension.EndsWith( "js" ) || extension.EndsWith( "css" ) )
                    fileEncoding = "UTF-8";

                try {
                    return new WebResourceResponse( mimeType, fileEncoding, m_Assets.Open( fileUrl ) );
                } catch {
                    // ignore
                }
            }

            return base.ShouldInterceptRequest( view, request );
        }
    }

这里发生了几件事。如果您打算在本地主机上提供webview,我想您的“我发现了”是正确的解决方案


我正在尝试使用Vue实例在webview中脱机运行。这就是JustinHui的回答对我起作用的地方。我没有手动删除vue cli生成的index.html中的斜杠,而是转到vue.config.js并将publicPath设置为空字符串。这就解决了问题。

Demo github repo演示了这个问题:如何在应用程序中打开chrome调试器?它不在应用程序中-一旦启动了android emulator并带有应用程序,就可以在计算机上打开chrome://inspect/#devices 您将看到仿真器及其下方的inspect链接。检查这篇文章:这是另一篇,可能更为最新-至少屏幕截图与我看到的完全一致(不是在谷歌上-可能是因为我使用的是windows而不是MacOS)。这是我第一次尝试,但没有成功。为了避免手动修复所有URL,我实现了ShouldInterceptRequest来提供来自android资产的内容。当我放置brekpoint时,它会停在那里,正确地修复URL,但最终页面仍然为空。若要在生成过程中自动删除“/”,请在vue cli 3/4项目设置中将publicPath:“./”添加到vue.config.js中。事实证明,这是正确的方法,但是,我必须为publicPath和assetsdir使用空字符串,这正是我所需要的。谢谢你。我试过这个,但只有从我的服务工作。file://URL只加载了部分页面,并没有执行所有脚本。。。当我在桌面计算机上的浏览器中打开“index.html”时,也会发生同样的情况followup-将publicPath设置为./没有帮助,但将其设置为空字符串实际上起到了作用。还将assetsDir设置为空字符串,并为路由器从历史模式切换到哈希模式。
wv.LoadUrl( "http://localhost/index.html" );

    // view client to serve the web from assets folder correctly
    public class MyWebViewClient : WebViewClient {

        private AssetManager m_Assets;

        public MyWebViewClient( AssetManager assets ) {
            m_Assets = assets;
        }

        public static string GetMimeType( String url ) {
            String type = null;
            String extension = url.Split( '.' ).Last();
            if ( extension != null ) {
                if ( extension == "css" ) {
                    return "text/css";
                } else if ( extension == "js" ) {
                    return "text/javascript";
                } else if ( extension == "png" ) {
                    return "image/png";
                } else if ( extension == "gif" ) {
                    return "image/gif";
                } else if ( extension == "jpg" ) {
                    return "image/jpeg";
                } else if ( extension == "jpeg" ) {
                    return "image/jpeg";
                } else if ( extension == "woff" ) {
                    return "application/font-woff";
                } else if ( extension == "woff2" ) {
                    return "application/font-woff2";
                } else if ( extension == "ttf" ) {
                    return "application/x-font-ttf";
                } else if ( extension == "eot" ) {
                    return "application/vnd.ms-fontobject";
                } else if ( extension == "svg" ) {
                    return "image/svg+xml";
                }

                type = "text/html";
            }

            return type;
        }

        public override WebResourceResponse ShouldInterceptRequest( WebView view, IWebResourceRequest request ) {

            if ( request.Url != null && request.Url.Path != null && request.Url.Host == "localhost" ) {
                var mimeType = GetMimeType( request.Url.Path );
                var fileUrl = request.Url.Path
                    .Replace( "file://", "" )
                    .Replace( "android_asset/", "" )
                    .Trim( '/' );

                string extension = request.Url.Path.Split( '.' ).Last();;
                string fileEncoding = "application/octet-stream";
                if ( extension.EndsWith( "html" ) || extension.EndsWith( "js" ) || extension.EndsWith( "css" ) )
                    fileEncoding = "UTF-8";

                try {
                    return new WebResourceResponse( mimeType, fileEncoding, m_Assets.Open( fileUrl ) );
                } catch {
                    // ignore
                }
            }

            return base.ShouldInterceptRequest( view, request );
        }
    }