80690


.NET Framework4.8 の WPF で開発してます。  
Window に配置した [WebView2 コントロール](https://docs.microsoft.com/ja-jp/microsoft-
edge/webview2/)にhtml を表示させていますが、img
タグでインターネット上の画像は表示されますが、ローカルに配置した画像をフルパスで表示させようとすると表示されません。  
[WebView2 の開発者ツール](https://docs.microsoft.com/ja-jp/microsoft-edge/devtools-
guide-chromium/)で調べると「Not allowed to load local resource」とエラーが出ています。

imgタグの src に指定したパスを調べても問題は見られず、Chrome のアドレスバーに貼り付けると画像は正常に表示されます。また html を
Chromeで開くと img タグのローカル画像は表示されます。

どうにかローカルの画像を WebView2 で表示させる方法はないものでしょうか？


CC BY-SA 4.0
2021-08-04T06:04:23.357
80589
2021-08-09T11:24:15.700
2021-08-04T08:19:49.803
3060
19617
question
c# html .net wpf
WebView2 でローカルの画像を表示させたい


手元の.NET 4.7.2(WebView2 1.0.902.49)環境では下記のコードで問題なく画像が表示されています。

htmlファイルの場所はローカルでしょうか。  
またChromeではなくEdgeでも問題なく画像が表示されるでしょうか。

類似質問の回答: [File URL "Not allowed to load local resource" in the Internet
Browser](https://stackoverflow.com/a/35014520)

**xaml**

[code]

    <Window x:Class="WpfApp2.MainWindow" 
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
            xmlns:local="clr-namespace:WpfApp2" 
            xmlns:wv="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf" 
            mc:Ignorable="d" 
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <wv:WebView2 Name="MyView" Source="C:\test\html\index.html"/>
        </Grid>
    </Window>
    
[/code]

**html**

[code]

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE html>
    <html>
    <body>
    <img src="file:///C:/test/html/test.png"/>
    </body>
    </html>
    
[/code]


CC BY-SA 4.0
2021-08-04T06:31:28.937
80590
2021-08-04T06:31:28.937
9820
80589
answer


WebView2.Source プロパティとWebView2.NavigateToString
メソッドの挙動を比較してみました。WebView2.Source プロパティはimgタグでローカル画像が表示されますが、NavigateToString
メソッドでは表示されません。

[code]

    using System;
    using System.IO;
    using System.Text;
    using System.Windows;
    using Microsoft.Web.WebView2.Core;
    
    namespace WebView2Test {
        public partial class MainWindow : Window {
            public MainWindow() {
                InitializeComponent();
            }
    
            private async void Window_ContentRendered(object sender, EventArgs e) {
                var webView2Environment = await CoreWebView2Environment.CreateAsync();
                await wv2.EnsureCoreWebView2Async(webView2Environment);
    
                // これはローカル画像が表示される
                wv2.Source= new Uri(@"file:///C:\Users\xxxx\Desktop\test2.html");
    
                // これはローカル画像が表示されない
                var sr = new StreamReader(@"C:\Users\xxxx\Desktop\test2.html", Encoding.UTF8);
                var html = sr.ReadToEnd();
                wv2.NavigateToString(html);
            }
        }
    }
    
[/code]

推測するに NavigateToString
メソッドはセキュリティの関係上、ローカルファイルへアクセスできないようにしているのでしょうか？そこで回避策として、いったんローカルに加工したHTMLを保存し、Source
プロパティで読み込むようにしてみました。

[code]

    private async void Window_ContentRendered(object sender, EventArgs e) {
        var webView2Environment = await CoreWebView2Environment.CreateAsync();
        await wv2.EnsureCoreWebView2Async(webView2Environment);
        var path = @"C:\Users\xxxx\Desktop\test3.html";
        using (var sr = new StreamReader(@"C:\Users\xxxx\Desktop\test2.html", Encoding.UTF8)){
            var html = sr.ReadToEnd();
            // html の加工処理を行なう・・・・
            html = html.Replace("<img src", "<br/><img src");
            using (var wr = new StreamWriter(path, false, Encoding.UTF8)) {
                wr.WriteLine(html);
            }
        }
        wv2.Source = new Uri(path);
    }
    
[/code]

ストリームを書き込むオーバーヘッドが発生するため釈然としない思いがありますが、当面これで回避しようと思います。


CC BY-SA 4.0
2021-08-05T05:54:09.363
80611
2021-08-05T05:54:09.363
19617
80589
answer


fileプロトコルはなにかと制限厳しいので難しいのではないでしょうか？  
（NavigateToStringはローカルならではの特例が適用されないようなので）

WebView2のissueに登録されていた例では、SetVirtualHostNameToFolderMappingを使って特定のホスト名でローカルファイルに見せかけるテクニックで回避する例が紹介されていますね。

<https://github.com/MicrosoftEdge/WebView2Feedback/issues/642#issuecomment-736760565>

上記を参考に手元で試したもの：

[code]

            var webView2Environment = await CoreWebView2Environment.CreateAsync();
            await MyView.EnsureCoreWebView2Async(webView2Environment);
    
            var localFolderPath = @"f:\tmp\";
            MyView.CoreWebView2.SetVirtualHostNameToFolderMapping("MyFiles", localFolderPath, CoreWebView2HostResourceAccessKind.Allow);
    
            // http かつ MyFiles というホスト名に置換しているのがミソ
            MyView.NavigateToString(@"<html>
    <body>
    <img src=""http://MyFiles/1.jpg"" />
    </body>
    </html>");
    
[/code]


CC BY-SA 4.0
2021-08-09T11:24:15.700
80690
2021-08-09T11:24:15.700
4684
80589
answer