protected override async Task HandleWebResourceRequest(CoreWebView2WebResourceRequestedEventArgs eventArgs) { // Unlike server-side code, we get told exactly why the browser is making the request, // so we can be smarter about fallback. We can ensure that 'fetch' requests never result // in fallback, for example. var allowFallbackOnHostPage = eventArgs.ResourceContext == CoreWebView2WebResourceContext.Document || eventArgs.ResourceContext == CoreWebView2WebResourceContext.Other; // e.g., dev tools requesting page source // Get a deferral object so that WebView2 knows there's some async stuff going on. We call Complete() at the end of this method. using var deferral = eventArgs.GetDeferral(); var requestUri = QueryStringHelper.RemovePossibleQueryString(eventArgs.Request.Uri); // First, call into WebViewManager to see if it has a framework file for this request. It will // fall back to an IFileProvider, but on WinUI it's always a NullFileProvider, so that will never // return a file. if (TryGetResponseContent(requestUri, allowFallbackOnHostPage, out var statusCode, out var statusMessage, out var content, out var headers) && statusCode != 404) { // NOTE: This is stream copying is to work around a hanging bug in WinRT with managed streams. // See issue https://github.com/microsoft/CsWinRT/issues/670 var memStream = new MemoryStream(); content.CopyTo(memStream); var ms = new InMemoryRandomAccessStream(); await ms.WriteAsync(memStream.GetWindowsRuntimeBuffer()); var headerString = GetHeaderString(headers); eventArgs.Response = _coreWebView2Environment !.CreateWebResourceResponse(ms, statusCode, statusMessage, headerString); }
private void OnRequestInterceptCallback(IntPtr context, IntPtr request, IntPtr userdata) { if (request == IntPtr.Zero) { return; } var url = NativeWebView.GetInterceptRequestUrl(request); if (url.StartsWith(AppOrigin)) { var allowFallbackOnHostPage = url.EndsWith("/"); url = QueryStringHelper.RemovePossibleQueryString(url); if (_webviewManager !.TryGetResponseContentInternal(url, allowFallbackOnHostPage, out var statusCode, out var statusMessage, out var content, out var headers)) { var header = $"HTTP/1.0 200 OK\r\n"; foreach (var item in headers) { header += $"{item.Key}:{item.Value}\r\n"; } header += "\r\n"; using (MemoryStream memstream = new MemoryStream()) { content.CopyTo(memstream); var body = memstream.ToArray(); NativeWebView.SetInterceptRequestResponse(request, header, body, (uint)body.Length); } return; } } NativeWebView.IgnoreInterceptRequest(request); }
protected virtual async Task HandleWebResourceRequest(ICoreWebView2WebResourceRequestedEventArgsWrapper eventArgs) { // Unlike server-side code, we get told exactly why the browser is making the request, // so we can be smarter about fallback. We can ensure that 'fetch' requests never result // in fallback, for example. var allowFallbackOnHostPage = eventArgs.ResourceContext == CoreWebView2WebResourceContextWrapper.Document || eventArgs.ResourceContext == CoreWebView2WebResourceContextWrapper.Other; // e.g., dev tools requesting page source var requestUri = QueryStringHelper.RemovePossibleQueryString(eventArgs.Request.Uri); // First, call into WebViewManager to see if it has a framework file for this request. It will // fall back to an IFileProvider, but on WinUI it's always a NullFileProvider, so that will never // return a file. if (TryGetResponseContent(requestUri, allowFallbackOnHostPage, out var statusCode, out var statusMessage, out var content, out var headers)) { // NOTE: This is stream copying is to work around a hanging bug in WinRT with managed streams var memStream = new MemoryStream(); content.CopyTo(memStream); var ms = new InMemoryRandomAccessStream(); await ms.WriteAsync(memStream.GetWindowsRuntimeBuffer()); var headerString = GetHeaderString(headers); eventArgs.SetResponse(ms, statusCode, statusMessage, headerString); } }
private byte[] GetResponseBytes(string url, out string contentType, out int statusCode) { var allowFallbackOnHostPage = AppOriginUri.IsBaseOfPage(url); url = QueryStringHelper.RemovePossibleQueryString(url); if (_webViewHandler._webviewManager !.TryGetResponseContentInternal(url, allowFallbackOnHostPage, out statusCode, out var statusMessage, out var content, out var headers)) { statusCode = 200; using var ms = new MemoryStream(); content.CopyTo(ms); content.Dispose(); contentType = headers["Content-Type"]; return(ms.ToArray()); }
private async Task InitializeWebView2() { await _webview.CreateEnvironmentAsync().ConfigureAwait(true); await _webview.EnsureCoreWebView2Async(); ApplyDefaultWebViewSettings(); _webview.CoreWebView2.AddWebResourceRequestedFilter($"{AppOrigin}*", CoreWebView2WebResourceContextWrapper.All); var removeResourceCallback = _webview.CoreWebView2.AddWebResourceRequestedHandler((s, eventArgs) => { // Unlike server-side code, we get told exactly why the browser is making the request, // so we can be smarter about fallback. We can ensure that 'fetch' requests never result // in fallback, for example. var allowFallbackOnHostPage = eventArgs.ResourceContext == CoreWebView2WebResourceContextWrapper.Document || eventArgs.ResourceContext == CoreWebView2WebResourceContextWrapper.Other; // e.g., dev tools requesting page source var requestUri = QueryStringHelper.RemovePossibleQueryString(eventArgs.Request.Uri); if (TryGetResponseContent(requestUri, allowFallbackOnHostPage, out var statusCode, out var statusMessage, out var content, out var headers)) { var headerString = GetHeaderString(headers); eventArgs.SetResponse(content, statusCode, statusMessage, headerString); } }); // The code inside blazor.webview.js is meant to be agnostic to specific webview technologies, // so the following is an adaptor from blazor.webview.js conventions to WebView2 APIs await _webview.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(@" window.external = { sendMessage: message => { window.chrome.webview.postMessage(message); }, receiveMessage: callback => { window.chrome.webview.addEventListener('message', e => callback(e.data)); } }; ").ConfigureAwait(true); QueueBlazorStart(); var removeMessageCallback = _webview.CoreWebView2.AddWebMessageReceivedHandler(e => MessageReceived(new Uri(e.Source), e.WebMessageAsString)); }
protected virtual Task HandleWebResourceRequest(CoreWebView2WebResourceRequestedEventArgs eventArgs) { #if WEBVIEW2_WINFORMS || WEBVIEW2_WPF // Unlike server-side code, we get told exactly why the browser is making the request, // so we can be smarter about fallback. We can ensure that 'fetch' requests never result // in fallback, for example. var allowFallbackOnHostPage = eventArgs.ResourceContext == CoreWebView2WebResourceContext.Document || eventArgs.ResourceContext == CoreWebView2WebResourceContext.Other; // e.g., dev tools requesting page source var requestUri = QueryStringHelper.RemovePossibleQueryString(eventArgs.Request.Uri); if (TryGetResponseContent(requestUri, allowFallbackOnHostPage, out var statusCode, out var statusMessage, out var content, out var headers)) { var headerString = GetHeaderString(headers); eventArgs.Response = _coreWebView2Environment.CreateWebResourceResponse(content, statusCode, statusMessage, headerString); } #elif WEBVIEW2_MAUI // No-op here because all the work is done in the derived WinUIWebViewManager #endif return(Task.CompletedTask); }
public override WebResourceResponse?ShouldInterceptRequest(AWebView?view, IWebResourceRequest?request) { if (request is null) { throw new ArgumentNullException(nameof(request)); } var allowFallbackOnHostPage = false; var requestUri = request?.Url?.ToString(); var appBaseUri = new Uri(AppOrigin); var fileUri = requestUri != null ? new Uri(requestUri) : null; if (fileUri != null && appBaseUri.IsBaseOf(fileUri)) { var relativePath = appBaseUri.MakeRelativeUri(fileUri).ToString(); if (string.IsNullOrEmpty(relativePath)) { // For app root, use host page (something like wwwroot/index.html) allowFallbackOnHostPage = true; } } requestUri = QueryStringHelper.RemovePossibleQueryString(requestUri); if (requestUri != null && _webViewHandler != null && _webViewHandler.WebviewManager != null && _webViewHandler.WebviewManager.TryGetResponseContentInternal(requestUri, allowFallbackOnHostPage, out var statusCode, out var statusMessage, out var content, out var headers)) { var contentType = headers["Content-Type"]; return(new WebResourceResponse(contentType, "UTF-8", statusCode, statusMessage, headers, content)); } return(base.ShouldInterceptRequest(view, request)); }