如何通过CefSharp.Wpf浏览器控件显示带有本地文件资源的网页

时间:2020-04-06 13:57:57

标签: wpf cefsharp

我正在尝试使用CefSharp.Wpf NuGet软件包(v79.1.360)从磁盘显示一个简单的html网页。

该页面具有与页面本身不同目录中的本地文件(javascript,css等)的依赖关系。

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />

    <link rel="stylesheet" type="text/css" href="file:///G:/AngularJS/Framework/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="MyApp.css">

    <script src="file:///G:/AngularJS/Framework/angular.min.js"></script>
    <script src="file:///G:/AngularJS/Framework/jquery.min.js"></script>
    <script src="file:///G:/AngularJS/Framework/bootstrap.min.js"></script>
    <script src="MyApp.js"></script>

    <title></title>
</head>
<body>
            <p class="font-weight-bold">Select address</p>

            <table class="table table-hover">
                <thead>
                    <tr class="bg-primary">
                        <th scope="col">ID</th>
                        <th scope="col">Name</th>
                        <th scope="col">Code</th>
                        <th scope="col">City</th>
                        <th scope="col">Street</th>
                    </tr>
                </thead>

                <tbody>
                    <tr ng-repeat="address in Model.AddressList"
                        ng-click="Model.PickRow(address)"
                        ng-style="{'background-color': address.Background}">
                        <td>{{address.Id}}</td>
                        <td>{{address.Name}}</td>
                        <td>{{address.PostalCode}}</td>
                        <td>{{address.City}}</td>
                        <td>{{address.Street}}</td>
                    </tr>
                </tbody>
            </table>
</body>
</html>

我可以在基于铬的Web浏览器(Firefox)上以修改后的设置显示页面: security.fileuri.strict_origin_policy false

-> Firefox不是基于Chrome的Web浏览器,因此我使用google chrome对其进行了测试,并且也可以使用。

在我的网络研究中,我发现了与此问题相关的帖子(不幸的是,该帖子来自2014年):

https://github.com/cefsharp/CefSharp/issues/572

因此,我尝试为cef Sharp控件设置浏览器设置:

<Window x:Class="WebControl.MyWebBrowser"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cefSharpCore="clr-namespace:CefSharp;assembly=CefSharp.Core"
        xmlns:cefSharpWpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
        Height="300" Width="300">
    <Grid>
        <cefSharpWpf:ChromiumWebBrowser>
            <cefSharpWpf:ChromiumWebBrowser.BrowserSettings>
                <cefSharpCore:BrowserSettings WebSecurity="Disabled"
                                              FileAccessFromFileUrls="Enabled"
                                              UniversalAccessFromFileUrls="Enabled"/>
            </cefSharpWpf:ChromiumWebBrowser.BrowserSettings>
        </cefSharpWpf:ChromiumWebBrowser>
    </Grid>
</Window>

但这不起作用。我还尝试在文件后面的代码中设置设置,但没有成功。

长话短说:

Current result Expected result

如果有人有解决方案,请告诉我。

预先感谢您阅读这篇文章:-)

1 个答案:

答案 0 :(得分:1)

感谢amaitland将我引向正确的方向:

我强烈建议不要从本地磁盘加载文件时使用file:///。应用了不同的安全限制,并且存在许多限制。我建议使用Scheme处理程序或实现自己的IResourceRequestHandlerFactory。 (加载数据:编码的URI也非常方便,特别是对于OffScreen项目而言)。 如果您选择忽略此建议,则必须自己使用file:///解决所有问题。 ceforum是最好的资源。

复制自:https://github.com/cefsharp/CefSharp/wiki/General-Usage#file-uri-file

解决方案是创建自定义方案处理程序:

https://github.com/cefsharp/CefSharp/wiki/General-Usage#scheme-handler

1)我向我的Visual Studio项目中添加了angular,bootstrap和jquery文件作为资源。

2)我创建了DiskSchemeHandlerFactory.cs:

public class DiskSchemeHandlerFactory : ISchemeHandlerFactory
{
    private static readonly string _SchemeName = "disk";
    private static readonly IDictionary<string, string> _ResourceDictionary;


    public string SchemeName
    {
        get { return _SchemeName; }
    }


    static DiskSchemeHandlerFactory()
    {
        _ResourceDictionary = new Dictionary<string, string>
        {
            { "/angular.min.js", Properties.Resources.angular_min },
            { "/angular.min.js.map", Properties.Resources.angular_min_js },
            { "/bootstrap.min.js", Properties.Resources.bootstrap_min1 },
            { "/bootstrap.min.css", Properties.Resources.bootstrap_min },
            { "/jquery.min.js", Properties.Resources.jquery_min }
        };
    }


    public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
    {
        //Notes:
        // - The 'host' portion is entirely ignored by this scheme handler.
        // - If you register a ISchemeHandlerFactory for http/https schemes you should also specify a domain name
        // - Avoid doing lots of processing in this method as it will affect performance.
        // - Uses the Default ResourceHandler implementation

        var uri = new Uri(request.Url);
        var fileName = uri.AbsolutePath;

        string resource;
        if (_ResourceDictionary.TryGetValue(fileName, out resource) && !string.IsNullOrEmpty(resource))
        {
            var fileExtension = Path.GetExtension(fileName);
            return ResourceHandler.FromString(resource, fileExtension);
        }

        return null;
    }
}

3)我修改了MyWebBrowser.xaml.cs的静态构造函数:

    static MyWebBrowser()
    {
        if (Cef.IsInitialized == false)
        {
            var diskSchemeHandlerFactory = new DiskSchemeHandlerFactory();

            var settings = new CefSettings();
            settings.RegisterScheme(new CefCustomScheme()
            {
                SchemeName = diskSchemeHandlerFactory.SchemeName,
                SchemeHandlerFactory = diskSchemeHandlerFactory
            });

            Cef.Initialize(settings);
        }
    }

4)最后,我更改了html页面的文件路径:

<script src="disk://angular/angular.min.js"></script>
<script src="disk://jquery/jquery.min.js"></script>
<script src="disk://bootstrap/bootstrap.min.js"></script>

也许我也将其修改为也可以使用完整文件路径。有了这个解决方案,我每次想使用另一个文件时都必须编译我的项目...

相关问题