So, you want to serve page via
Chromium Embedded Framework, but you don’t want to host http server? There are 2 ways to achieve it, but if you are only interested in a quick solution, scroll down to
custom file protocol.
why you can’t just use file protocol
If you are here, then I guess that you have already tried using
file:// protocol to make it work, but you have failed - your styles are not applied, or images don’t show up. Why? Due to security restrictions that come with chromium when using file protocol. Let’s say that you have bundled your web application into this structure:
and in your
index.html you are requesting one of graphics located in
Image will not be rendered, because of an error that looks lke this:
XMLHttpRequest cannot load file:///.../images/arrow.svg. Cross origin requests are only supported for HTTP.
Chromium will not allow you to load file that has a different origin (basically, located in different folder). Why it happens is because a directory tree
is not treated as a single origin. Anything that is a child, relative to your index.html (in this case) is not considered to be a single origin. To read more about it, you can check out this chromium issue.
--allow-file-access-from-files is not a good idea
Sure, running chrome with this flag will make your app work - unfortunatelly, it will open your whole file system to malicious code.
Imagine that someone injected this into your code:
This snippet could easily reveal all you important stuff (keeping your passwords in png? Sure, why not). That’s why we need:
custom file protocol
CEF allows you to specify custom protocols that allow you to craft response sufficient for your needs. What we want to create is something similar to file protocol, but this something should allow you to work with files from whole directory tree. For purpouse of this article let’s call it
custom protocol. Let’s get to work.
We are building our class basing on SchemeHandler.cs provided by Cef.
At this point we are almost good to go. Now go to place, where you call Cef.Initialize(…), and add this code:
It is important to register scheme
before initializing CEF.
CefSharp version used for this code is v63.0.0.