我有一个简单的web应用程序,我想在WinUI应用程序中运行,它可以获取外部HTML内容:
private async fetchHtml() {
const url = document.querySelector<HTMLInputElement>("#txt-url")!.value;
const html = await fetch(url).then(r => r.text());
document.querySelector<HTMLTextAreaElement>("#txt-html")!.value = html;
}
显然,这会导致CORS错误。我想禁用它,但找不到WinUI3:的任何方法
WinUI中的WebView2没有占用CoreWebView2EnvironmentOptions
的EnsureCoreWebView2Async
重载,因此此答案没有帮助。
URL是外部URL,因此此答案建议的SetVirtualHostNameToFolderMapping
也没有帮助。
我尝试注入我自己的CORS头,但它在fetch
上不起作用(WebResourceResponseReceived
事件不仅在fetch
请求上触发):
c.WebResourceResponseReceived += (_, e) =>
{
var origin = e.Request.Headers.FirstOrDefault(q => q.Key == "Origin").Value;
if (!string.IsNullOrEmpty(origin))
{
e.Response.Headers.AppendHeader("Access-Control-Allow-Origin",
new Uri(e.Request.Uri).GetLeftPart(UriPartial.Authority));
e.Response.Headers.AppendHeader("Access-Control-Allow-Methods", "*");
e.Response.Headers.AppendHeader("Access-Control-Allow-Headers", "*");
}
};
因此,实际上您需要在WebResourceRequested
事件中处理代理请求。WebResourceResponseReceived
在浏览器处理请求后被触发。
若要手动代理请求,您需要首先设置web资源请求筛选器。
// CoreWebView2WebResourceContext.XmlHttpRequest is triggered
// by fetches for some reason. This filter will listen for any URI.
this.webView.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.XmlHttpRequest);
然后,您可以像WebResourceResponseReceived
一样设置侦听器
this.webView.CoreWebView2.WebResourceRequested += this.CoreWebView2_WebResourceRequested;
因此,要代理请求,您需要设置一个HttpClient并手动处理请求。
例如,这将代理所有请求,假设httpClient
被定义为HttpClient
:
private void CoreWebView2_WebResourceRequested(object sender, CoreWebView2WebResourceRequestedEventArgs e)
{
HttpRequestMessage request = new(new HttpMethod(e.Request.Method), e.Request.Uri)
{
Content = new StreamContent(e.Request.Content)
};
foreach (KeyValuePair<string, string> header in e.Request.Headers)
{
// Copy base headers
request.Headers.TryAddWithoutValidation(header.Key, header.Value);
// Copy content headers
request.Content.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
// Make the request
HttpResponseMessage response = httpClient.Send(request);
// Custom headers
response.Headers.Add("Access-Control-Allow-Origin", "*");
// Webview2 Response expecting headers in a string with following format:
// key: value
// header2: value
List<string> headers = response.Headers.Select(h => $"{h.Key}: {string.Join(",", h.Value)}").ToList();
// Create Webview2 response
CoreWebView2WebResourceResponse webView2WebResourceResponse = this.webView.CoreWebView2.Environment.CreateWebResourceResponse(
response.Content.ReadAsStream(),
(int)response.StatusCode,
response.ReasonPhrase,
string.Join('n', headers));
e.Response = webView2WebResourceResponse;
}
注意
构建响应对象时不应使用async
方法。COM层不尊重线程。