Как отобразить веб-страницу с помощью браузера CefSharp.Wpf с локальными файловыми ресурсами - PullRequest
0 голосов
/ 06 апреля 2020

Я пытаюсь использовать пакет CeGSharp.Wpf NuGet (v79.1.360) для отображения простой html веб-страницы с диска.

Страница имеет зависимости от локальных файлов (javascript, css, et c. ...) в другом каталоге, чем сама страница.

<!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>

Я могу отобразить страницу в веб-браузере на основе хрома (Firefox) с измененными настройками: security.fileuri.strict_origin_policy false

-> Firefox не является веб-браузером на основе хрома, поэтому я протестировал его с помощью 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>

Но это не работает. Я также попытался установить настройки в коде файла без успеха.

Короче говоря:

Текущий результат Ожидаемый результат

Если у кого-то есть решение, пожалуйста, дайте мне знать.

Заранее спасибо за чтение поста: -)

1 Ответ

1 голос
/ 07 апреля 2020

Спасибо 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 - обработчик

1) Я добавил angular, bootstrap и jquery файлы в качестве ресурсов для моего проекта Visual Studio.

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) Я изменил конструктор stati c 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>

Возможно, я изменил ее, чтобы она работала и с полными путями к файлам. С этим решением мне приходится компилировать свой проект каждый раз, когда я хочу использовать другой файл ...

...