我正在嘗試使用從 WebView2 的包含應用程式傳入的源在 WebView2 中動態創建影像。
源影像存在于檔案系統上的任意位置。為了允許 WebView2 訪問影像,我使用了 SetVirtualHostNameToFolderMapping,它將 webview 中的主機名映射到某個檔案夾。
我希望這僅在 webview 內部進行一些互動后發生,使用postMessage和WebMessageReceived事件,如此處所述。
如果我在 WebMessageReceived 處理程式之外呼叫SetVirtualHostNameToFolderMapping,即使在我使用 導航到 HTML 之后,webview 也會加載影像。NavigateToString
但是,如果我在WebMessageReceived處理程式中呼叫SetVirtualHostNameToFolderMapping:
webview.CoreWebView2.WebMessageReceived = (s, e) => {
webview.CoreWebView2.SetVirtualHostNameToFolderMapping(
"assets",
@"C:\path\to\folder",
CoreWebView2HostResourceAccessKind.Allow
);
webview.CoreWebView2.PostWebMessageAsString(@"breakpoint.bmp");
};
webview 找不到圖片;它失敗了:
加載資源失敗:net::ERR_NAME_NOT_RESOLVED
我該如何除錯呢?我可以使用其他替代方法來做類似的事情嗎?
XAML:
<Window x:Class="_testWebviewDialogs.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wv="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf">
<wv:WebView2 x:Name="webview" />
</Window>
代碼隱藏:
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.Web.WebView2.Core;
namespace _testWebviewDialogs;
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
Loaded = async (s, e) => await initializeAsync();
}
private async Task initializeAsync() {
await webview.EnsureCoreWebView2Async();
webview.CoreWebView2.WebMessageReceived = (s, e) => {
webview.CoreWebView2.SetVirtualHostNameToFolderMapping(
"assets",
@"C:\path\to\folder",
CoreWebView2HostResourceAccessKind.Allow
);
webview.CoreWebView2.PostWebMessageAsString(@"breakpoint.bmp");
};
var html = await File.ReadAllTextAsync("container.html");
webview.NavigateToString(html);
}
}
container.html:
<!DOCTYPE html>
<html>
<body>
<button id="button1">Click me</button>
<img id ="img1" src="" />
<script>
document.getElementById("button1").addEventListener('click', ev => {
chrome.webview.postMessage('source');
});
window.chrome.webview.addEventListener('message', event => {
document.getElementById('img1').src = `https://assets/${event.data}`;
});
</script>
</body>
</html>
uj5u.com熱心網友回復:
我為此提出了一個問題。根據回應,記錄了此行為:
由于當前頁面的資源加載器可能已經創建并運行,對映射的更改可能不會應用于當前頁面,需要重新加載頁面以應用新映射。(來源)
但是可以創建(和重新創建)指向不同目標路徑的符號鏈接,并將虛擬主機名映射到該符號鏈接。虛擬主機映射使用當前的符號鏈接目標。
var symlinkPath =
Path.Combine(
Path.GetDirectoryName(
Assembly.GetExecutingAssembly().Location!
)!,
"assets"
);
Directory.CreateDirectory(symlinkPath);
webview.CoreWebView2.SetVirtualHostNameToFolderMapping(
"assets",
symlinkPath,
CoreWebView2HostResourceAccessKind.Allow
);
webview.CoreWebView2.WebMessageReceived = (s, e) => {
Directory.Delete(symlinkPath);
Directory.CreateSymbolicLink(symlinkPath, @"C:\path\to\target\directory");
webview.CoreWebView2.PostWebMessageAsString(@"breakpoint.bmp");
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/475808.html
