-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Set origin with NavigateToString #530
Comments
@jhandley - I've added this feature request to our backlog! |
I'm running into the same thing. I'm trying to use a WebView2 to browse a dynamically-generated "preview" file of some HTML. I'd ideally like to use NavigateToString() to keep the preview HTML from every being written to disk, but if I do so, there seems to be no way to dynamically provide it the CSS, images, etc. that are referenced in the HTML since AddWebResourceRequestedFilter doesn't seem to currently work for NavigateToString(). This then makes NavigateToString() effectively useless. There are two issues here that I'd like to see resolved:
If both of these issues were resolved, that would make dynamic HTML viewing MUCH better using WebView2. Without those essential things (at least #1 but preferably both), we may have to go look at CefSharp instead, which we would prefer not to do. Thanks for considering adding them. |
@billhenn I ended up using cpp-httplib to run a local web server to serve the content rather than writing it to disk. It is pretty lightweight and easy to set up. For dynamically generated html you can use httplib::Server::Get() to map a url to a lambda that generates the response. If you have files on disk you can use httplib::Server::set_mount_point() to map a url to a folder on disk and it will serve files from that folder. You can combine the two so that http://localhost:1234/foo.html maps to a lambda and any other request to http://localhost:1234 gets mapped to a folder on disk. |
Thanks for the tip @jhandley, but we write our software in C#, so I'm not sure that would work for us. Regardless, with these couple relative minor enhancements to WebView2, none of this extra effort would be needed and building dynamic previews would be really easy. @ukandrewc - I'd rather not parse the HTML to try and locate CSS, images, etc. and then inject them inline somehow. I'd like to be able to serve them up on request from WebView2 using the existing events. It's just that the events aren't raised unless the HTML file is on the file system, which is the main issue. |
@billhenn In C# you could probably do something similar with HttpListener but of course would be much simpler for all if WebView2 was enhanced. |
@billhenn After I thought that through, I did think it could get tricky ;-) Do you mind if I ask why you don't want to use a temp file for your content? |
@ukandrewc In one usage scenario, I do write out a temp file for the HTML preview. However the problem is I need to leave it out there until the next render or when the app closes since the WebView processes it asynchronously. I had originally tried deleting it when the WebView2 indicated the content was rendered, but if another preview update request came in there in between, the WebView2 would sometimes show a not found error. Anyhow, all the messing around and managing of preview files gets annoying and if the app crashes, it leaves the preview file there. It all would be much cleaner to simply use NavigateToString() and be able to set the virtual base path. |
@billhenn In that case, you could use a skeleton HTML and fill the body from JS? I do that for a print preview, where I write and navigate to a file on startup with: That way, I only navigate once and just change the content when needed. |
@ukandrewc I have a folder hierarchy so the preview could be in any folder. Ideally I wouldn't ever have to write anything to the file system myself if the requested features were added. |
@billhenn Fair enough, just a suggestion ;-) |
I appreciate the suggestions @ukandrewc. The app I'm making is a Markdown editor that needs a HTML preview. The Markdown files can be in a large folder hierarchy so I need to be able to preview them at any level. If I write a "~preview.html" file containing the Markdown-to-HTML rendering to the folder where the Markdown file lives, then WebView2 works great. But per what I described above, I really don't want to have to write anything to the file system since the "~preview.html" files stick in the folder until the next preview occurs. |
@billhenn Completely understand, I'm just used to working from files, so it seems counter intuitive (to me) to not use temp files. I also find an advantage of easier debugging when I've written some rubbish that's supposed to be HTML ;-) The only other thing I do is to use a hash of the user path, and save to my own cache folder. Rather than saving to the user's folder. I can see that what you are asking for, is the same as WebBrowser control, and would be an advantage. |
I just loaded up CefSharp (the Chromium WPF browser) and tried out this scenario with them. They have a browser.LoadHtml() method (similar to WebView2.NavigateToString()) and an overload accepts a URL. If you specify the URL, then it will treat that as the URL of the HTML string and it will proceed as if the HTML came from that source. This is perfect because it allows me to provide the HTML result of my Markdown-to-HTML conversion and supply it right to the browser. Then by giving a "file://" URL of a faux .html file in the same folder as the original .md file, it automatically resolves all relative image/CSS/JS requests with no extra work by me. And their custom ResourceHandler class works too where I could intercept and provide any of those requests dynamically if I wanted to fulfill the request on my own, without ever hitting the file system. Unfortunately I will have to switch to CefSharp until WebView2 is able to support a similar mechanism where NavigateToString supports a faux URL parameter, and AddWebResourceRequestedFilter works when using this mechanism. @pagoe-msft - I'm not sure if you were following this thread, but please include my comments in your backlog notes. To sum up, the two things I need from WebView2 are:
Thank you for considering these enhancements. |
@billhenn really glad you've resolved your issue. Just in case you needed it, CEFSharp doesn't support proprietary video, audio codecs. Although you can buld the binaries yourself, and include them. |
@billhenn Thanks for the details and your scenario, we've got them in our backlog item! Sorry we couldn't support this scenario yet, but glad you got unblocked with CefSharp. @ukandrewc Thanks for the help and suggestions! |
Hi, we have the same need here! It would be very valuable for us if you could implement the proposed items from @billhenn |
@champnic I just want to double-check if the backlog item for this will allow HTML in NavigateToString be able to access local resources. The product I'm migrating from CEF uses Javascript as a scripting language, so previously a HTML file is generated that contains a Script element pointing to the script to run. I'm able to get this work if I use a static html and the The HTML wrapper I'm testing looks like this: Using |
@romanan Yes, part of this work will make accessing file:// resources easier from a NavigatToString. You can also try looking into the experimental Virtual Host Name API and see if that works for you here. It would allow you to specify a domain that is mapped to a folder on disc, and access resources in that location using http and the domain rather than file://. |
Any progress on this? I'd love to use the I'm saving the HTML to temporary files on the disk as a workaround for now, but it's clunky... |
We should begin work on this item in the next month or two. |
Hello, We are looking into providing a solution for this ask and have a couple of questions:
Thank you! |
I've switched jobs since working on this project and we long ago shipped the product with the workaround mentioned above so I'm not sure we would take advantage of this change at this point. @Oryxamus might have an opinion. |
Hi @nishitha-burman,
Here's my use caseI want to load resources from the local hard drive when I load HTML via the <head>
<link rel="stylesheet" href="C:\HtmlResources\bootstrap.min.css">
</head>
<body>
<img class="img-fluid" src="C:\HtmlResources\image1.jpg" />
<p><a href="myCustomLink">Click me</a></p>
</body> or alternatively, using the file:// protocol <head>
<link rel="stylesheet" href="file://C:/HtmlResources/bootstrap.min.css">
</head>
<body>
<img class="img-fluid" src="file://C:/HtmlResources/image1.jpg" />
<p><a href="myCustomLink">Click me</a></p>
</body> SetVirtualHostNameToFolderMappingI've also tried using the SetVirtualHostNameToFolderMapping method: webView2.CoreWebView2.SetVirtualHostNameToFolderMapping("myassets.local", @"C:/HtmlResources".FolderPath, CoreWebView2HostResourceAccessKind.Allow); and then refering to my resources like this: <head>
<link rel="stylesheet" href="http://myassets.local/bootstrap.min.css">
</head>
<body>
<img class="img-fluid" src="http://myassets.local/image1.jpg" />
<p><a href="myCustomLink">Click me</a></p>
</body> and this does load the resources, however, canceling navigation seems to be broken when using this method. private void WebView2_NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e)
{
//problem: when a link is clicked, the Url is "about:blank#blocked" and I cannot retreive the link (myCustomLink)
//problem: when a link is clicked, the navigation is not canceled event though I'm calling e.Cancel = true;
e.Cancel = true;
var linkName = Path.GetFileName(e.Uri);
CustomHandleLinkClicked(linkName);
} |
I was mentioned by @jhandley as I'm working on the product that he was building in 2020. Just to follow up, we run a local web server now and it solved our needs. However, if we were to use the new functionality, we would need to be able to supply an array of folder paths as our product needs to resolve content in several locations. That may not be a common enough use case to design for, especially with the local web server workaround. We have been very happy with WebView2 otherwise. It has allowed us to move a lot of UI development from MFC code to HTML/JavaScript. Continue the good work. |
Hi
Thank you |
Thank you everyone for your reply! We are currently investigating this :) |
Hi being able to set a base url when calling NavigateToString is the only feature I miss right now to port our app to using WebView2. Will this feature be implemented? Is there a schedule? Thanks. |
To access local resources (images, CSS, etc.. on the user's hard drive) in your HTML use Virtual Host Name Mapping with NavigateToString. webView.CoreWebView2.SetVirtualHostNameToFolderMapping(
"appassets.example", "assets", CoreWebView2HostResourceAccessKind.DenyCors);
string htmlContent =
@"
<head><link rel='stylesheet' href ='http://appassets.example/run.css' /></head>
<body>
<img src='http://appassets.example/grill.png' />
<p><a href='http://appassets.example/winrt_test.txt'> Click me</a></p>
</body>
";
webview.NavigateToString(htmlContent); |
Hi, thanks for the suggestion, but I'm afraid this won't help me. I use a html launcher page that writes a few settings to window.localStorage and then sets location.href to go to the real target url. this won't work with WebView2 because the page origin is about:blank. If there is an alternative way to access the local storage I could work around this. |
At this point, we do not support local storage to NavigateToString: localStorage |
@maxhrab - You should be able to use Chromium DevTools Protocol to modify local storage directly if that's valuable - https://chromedevtools.github.io/devtools-protocol/tot/DOMStorage/#method-setDOMStorageItem |
Any progress on this? The issue still seems to be there for |
Would really love to see NavigateToString with a baseUrl parameter. Is this still in the works? To answer the above questions for my scenario:
|
For folks adding their scenarios to this - If you can also include why SetVirtualHostnameToFolderMapping doesn't work for your scenario? |
SetVirtualHostnameToFolderMapping doesn't work for us because it doesn't handle relative paths. Our app allows users to create presentations that can include any html page. Pages may include dynamic content, and they typically reference other files - e.g. images, styles, etc. Presentations can be copied to arbitrary locations on disk or uploaded to any web server. References must therefore be relative since the absolute path can include any directory or domain. We can't require absolute virtual references because this is incompatible with previous versions of our app that supported relative paths (using the IE control on Windows). Also, we are cross platform so the pages must display properly in other platform's web controls. P.S. Correction from my previous post: we need a solution that works locally and over https. |
Any update on this? |
@krzysiek-b We had begun the investigation for this item, though I think it got deprioritized a bit with the introduction of SetVirtualHostnameToFolderMapping, which handled a lot of the cases (though not all). @aluhrs13 or @nishitha-burman will have the latest on it's current status. |
@aluhrs13 All other system webview solutions have the equivalent of setting base url when loading html: webkitgtk, WKWebView, and even IWebBrowser2. And the lack of feature in WebView2 causes problems for people writing cross platform software, they now must write 2 different implementations: one that just sets base url, and one that uses |
@aluhrs13 Hello! This would be useful for us on .NET MAUI since we ship a dev UI toolkit and don't have control over the HTML passed to the webview. We can modify the incoming HTML string to include a |
We also don't have control over the HTML being displayed. Having a baseURL is a must-have for us unfortunately. |
…bViewSource (#21892) ### Description of Change This PR removes the use of a 2nd "hidden" WebView2 that was used to parse and add a HTML `base` tag to the `head` tag when setting the HTML source of a WebView to a string. This was done by appending the `base` tag script to the start of the user's HTML string, which the WebView then adds into the `head` element. While this is technically not valid HTML, all current browsers correct this behavior. This is a work-around for the lack of being able to set the base URL when navigating to a string using WebView2 (MicrosoftEdge/WebView2Feedback#530). As a bonus, using `HtmlWebViewSource` should now be 2x faster 😅 ### Issues Fixed Fixes #21631
When setting HTML to display using ICoreWebView2::NavigateToString I would like to be able set the origin URL used by the browser for the page like you can do with the Android WebView method loadDataWithBaseURL
The origin URL would be used as the base for relative paths for resources. This allows you to set an HTML string that refers to images, scripts and stylesheets that are stored separately. In my case, on Android I set the base URL to a file:// and store images and stylesheets in that directory on disk.
I tried to simulate this using AddWebResourceRequestedFilter but the events only fire for http/https URLs so relative paths in HTML set by NavigateToString do not trigger these events.
I will try to make this work by writing out the HTML to a temporary file and use Navigate with a file:// url but I'd much rather avoid that using the same technique that I'm using on Android.
AB#29796279
The text was updated successfully, but these errors were encountered: