{"id":104879,"date":"2021-02-18T07:00:00","date_gmt":"2021-02-18T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=104879"},"modified":"2021-02-18T07:10:48","modified_gmt":"2021-02-18T15:10:48","slug":"20210218-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210218-00\/?p=104879\/","title":{"rendered":"How can I prevent a Windows Runtime WebView from loading any content beyond the initial request?"},"content":{"rendered":"<p>A customer wanted to navigate a XAML WebView control to a site and load only the HTML. No external script. No images. No CSS. Just the raw HTML returned from a single web request.<\/p>\n<p>You can do this by handling the <code>Web\u00adResource\u00adRequested<\/code> event. Let&#8217;s take <a href=\"https:\/\/github.com\/microsoft\/Windows-universal-samples\/blob\/08d7459c552fe1065d3fe195b3fe2a5d7ec3b567\/Samples\/XamlWebView\/\"> the WebView sample<\/a> and make these changes.<\/p>\n<pre>    public <a href=\"https:\/\/github.com\/microsoft\/Windows-universal-samples\/blob\/08d7459c552fe1065d3fe195b3fe2a5d7ec3b567\/Samples\/XamlWebView\/cs\/Scenario1_NavToUrl.xaml.cs#L22\">Scenario1_NavToUrl<\/a>()\r\n    {\r\n        this.InitializeComponent();\r\n        <span style=\"color: blue;\">WebViewControl.WebResourceRequested += OnResourceRequested;<\/span>\r\n    }\r\n\r\n    <span style=\"color: blue;\">Uri allowedUri = null;\r\n\r\n    void OnResourceRequested(WebView sender,\r\n             WebViewWebResourceRequestedEventArgs e)\r\n    {\r\n        if (e.Request.RequestUri != allowedUri)\r\n        {\r\n            e.Response = new Windows.Web.Http.HttpResponseMessage(\r\n                             Windows.Web.Http.HttpStatusCode.NotFound);\r\n        }\r\n    }<\/span>\r\n\r\n    private void NavigateWebview(string url)\r\n    {\r\n        try\r\n        {\r\n            Uri targetUri = new Uri(url);\r\n            <span style=\"color: blue;\">allowedUri = targetUri; \/\/ remember where we're going<\/span>\r\n            WebViewControl.Navigate(targetUri);\r\n        }\r\n        catch (UriFormatException ex)\r\n        {\r\n            \/\/ Bad address\r\n            AppendLog($\"Address is invalid, try again. Error: {ex.Message}.\");\r\n        }\r\n    }\r\n<\/pre>\n<p>When we navigate the WebView control, we remember the target URI in the <code>allowedUri<\/code> member variable. When the WebView is about to download some content, it raises the <code>WebResourceRequested<\/code> event to let the app know what is about to happen and give the opportunity to handle the request explicitly.<\/p>\n<p>In our case, we see whether the URI matches the <code>allowedUri<\/code>. If not, then we create a custom response that consists of error 404 (<i>Not found<\/i>). Maybe that&#8217;s not the best error code, but I&#8217;ll let you pick the error you want.<\/p>\n<p>Run the sample program and enter a URL like <code>https:\/\/visualstudio.microsoft.com\/<\/code>. The main HTML content loads, but all the other content is blocked.<\/p>\n<p>On the other hand, if you use a URL like <code>http:\/\/www.microsoft.com<\/code>, then nothing loads at all, because <code>http:\/\/www.microsoft.com<\/code> is a redirect to <code>https:\/\/www.microsoft.com<\/code>, and since that doesn&#8217;t match the <code>allowedUri<\/code>, we block it.<\/p>\n<p>Maybe that&#8217;s what you want. But if you want to allow redirects, you&#8217;ll have to follow the redirections and allow them, too. We&#8217;ll do that next time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You can intercept every resource request.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-104879","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>You can intercept every resource request.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104879","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=104879"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104879\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=104879"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=104879"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=104879"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}