我在Winform中创建了一个CefSharp浏览器,我需要在内存中动态构建一个CefSharp页面,然后让CefSharp呈现它。
理想情况下,我希望将包含HTML的字符串传递给构造函数,但它需要一个URL。答案可能是否定的,但是否有一个指令可以在字符串前面加上,让CefSharp知道它是一个包含网页的字符串?那么CefSharp会创建一个临时文件吗?
如果没有,Chromium文件夹设置在哪里?如果我把一个文件写到那里,然后把它作为一个完全限定的路径传递,它会起作用吗?我知道Chrome将支持像file:///Users/dmacdonald/Documents/myFile.htm这样的URL,但不确定如何使用临时结构来形成URL。
这是我的新代码,但我的浏览器对象没有ResourceHandler属性。我看到它有一个ResourceHandlerFactory
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CefSharp.WinForms;
using CefSharp;
namespace DanCefWinForm
{
public partial class Form1 : Form
{
public const string TestResourceUrl = "http://maps/resource/load";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
ChromiumWebBrowser browser = new ChromiumWebBrowser("http://maps/resource/load")
{
Dock = DockStyle.Fill,
};
var handler = browser.ResourceHandler;
browser.Location = new Point(20, 20);
browser.Size = new Size(100, 100);
this.Controls.Add(browser);
}
}
}
发布于 2016-09-18 17:22:11
简单的方法(一“文件”,一页)
LoadString()可用于直接从字符串加载:
ChromiumWebBrowser.LoadString(string html, string url);
或者,LoadHtml()可以以给定的编码方式从字符串加载:
ChromiumWebBrowser.LoadHtml(string html, string url, Encoding encoding);
我尝试了这两种方法,它们似乎都能工作,至少在CefSharp.Wpf v51.0.0中是这样的。根据WebBrowserExtensions.cs的说法,LoadHtml()
使用RegisterHandler()
注册ResourceHandler
。我不清楚LoadString()
是如何工作的,但这两个函数似乎具有相同的效果。
确保对假URL使用有效的URL格式,如:
https://myfakeurl.com
复杂的方法(多个“文件”,如doc +映像)
IResourceHandlerFactory
派生的类。使用VS2015,使用红色下划线的名称应该提供实现接口的选项。这个自动完成选项极大地简化了类的创建,所以一定要使用它。IResourceHandler
派生的类。如果可以的话,一定要使用实现界面自动完成选项.IResourceHandlerFactory
派生)中,有一个名为GetResourceHandler()
的函数。在此函数中,从步骤2(基于IResourceHandler
)返回派生类的一个新实例。在这里使用new
是必要的,因为网络浏览器可以同时请求多个文件。每个IResourceHandler
实例都应该处理来自浏览器的一个请求(不用担心,这是为您完成的)。ResourceHandlerFactory
的成员。将此成员设置为您在步骤1(从IResourceHandlerFactory
派生)中创建的类的新实例。这就是将Chromium浏览器控件链接到您的接口类的内容。在步骤3中,您将两个类连接在一起,因此我们有一个完整的链。ProcessRequest()
的函数。这是Web页面发出请求时调用的第一个函数。您的目标是记录请求的URL和任何POST数据,然后决定是否允许请求,调用callback.Continue()
或callback.Cancel()
。返回true继续。GetResponseHeaders()
的函数。这是第二个函数。您的目标是检查URL,可能从存储它的地方(但尚未发送)获取文件数据,确定响应长度(文件或字符串大小),并在响应对象中设置适当的状态代码。确保设置所有这些变量,以便请求能够正确进行。ReadResponse()
中完成请求。在此函数中,将步骤6中获取的数据写入dataOut
流。如果您的数据超过32 in,您可能需要发送多个块。绝对要确保将给定调用中的写入量限制为dataOut
流的长度。将bytesRead
设置为您在此特定调用中所写的任何内容。在最后一次调用中,当不再保留数据时,只需将bytesRead
设置为零并返回false
。因为给定文件可能多次被调用,所以一定要跟踪当前的读取位置,以便知道您所在的位置以及发送了多少数据。对于那些不熟悉此问题的人,您可以将直接编译到EXE中的数据文件存储到项目中,并将其“构建操作”设置为“嵌入式资源”,然后使用System.Reflection.Assembly.GetManifestResourceStream()
以编程方式加载数据。使用上述方法,不需要从磁盘创建或读取任何文件。
发布于 2018-04-24 20:14:56
您可能需要使用自定义方案处理程序,以便为本地文件服务,并“绕过”有关文件协议的铬安全性。
我在这件事上写了博客帖子。
您要添加的是您的方案处理程序及其工厂:
using System;
using System.IO;
using CefSharp;
namespace MyProject.CustomProtocol
{
public class CustomProtocolSchemeHandler : ResourceHandler
{
// Specifies where you bundled app resides.
// Basically path to your index.html
private string frontendFolderPath;
public CustomProtocolSchemeHandler()
{
frontendFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "./bundle/");
}
// Process request and craft response.
public override bool ProcessRequestAsync(IRequest request, ICallback callback)
{
var uri = new Uri(request.Url);
var fileName = uri.AbsolutePath;
var requestedFilePath = frontendFolderPath + fileName;
if (File.Exists(requestedFilePath))
{
byte[] bytes = File.ReadAllBytes(requestedFilePath);
Stream = new MemoryStream(bytes);
var fileExtension = Path.GetExtension(fileName);
MimeType = GetMimeType(fileExtension);
callback.Continue();
return true;
}
callback.Dispose();
return false;
}
}
public class CustomProtocolSchemeHandlerFactory : ISchemeHandlerFactory
{
public const string SchemeName = "customFileProtocol";
public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
{
return new CustomProtocolSchemeHandler();
}
}
}
然后在调用Cef.Initialize之前注册它:
var settings = new CefSettings
{
BrowserSubprocessPath = GetCefExecutablePath()
};
settings.RegisterScheme(new CefCustomScheme
{
SchemeName = CustomProtocolSchemeHandlerFactory.SchemeName,
SchemeHandlerFactory = new CustomProtocolSchemeHandlerFactory()
});
发布于 2015-02-24 16:06:11
有关为内存中字符串注册ResourceHandler
的示例,请参见ResourceHandler
。
正如您所看到的,它仍然有一个URL (web资源通常都有这个URL),但它可能是您的选择之一。
下面是GitHub搜索如何在WinForms (和WPF)示例应用程序中调用它:https://github.com/cefsharp/CefSharp/search?utf8=%E2%9C%93&q=RegisterTestResources
另一个,可能不太有利的选项,有一个临时文件(任何地方?)在本地文件系统中使用FileAccessFromFileUrlsAllowed
从以下评论中更新:
您现在使用的是什么CefSharp版本?注如果您查看github.com/CefSharp/CefSharp/ resource
并搜索,您将看到版本49中的API更改(查看该版本的最新更改)--请参阅下面的评论,以了解
https://stackoverflow.com/questions/28697613
复制相似问题