CefSharp自定义local协议加载本地PDF无显示问题求助
从你提供的日志信息可以直接定位到问题:Chrome内核(CefSharp基于此)的内容安全策略(CSP)阻止了自定义local协议的PDF资源加载。日志明确提示:
Refused to load plugin data from 'local://c/Users/abidh/Desktop/pdf.pdf' because it violates the following Content Security Policy directive: "object-src * blob: externalfile: file: filesystem: data:".
默认的CSP规则里,object-src允许的协议列表包含file:,但没有你自定义的local:,所以浏览器拒绝加载该资源——这也是为什么file协议能正常显示的原因。
下面提供两种简单有效的解决方案:
方案1:让自定义Scheme绕过CSP检查(推荐)
在注册自定义Scheme时,设置IsCspBypassing = true,这样CefSharp会直接跳过对该Scheme资源的CSP校验,无需修改任何CSP规则:
var settings = new CefSettings(); settings.RegisterScheme(new CefCustomScheme { SchemeName = CustomProtocolSchemeHandlerFactory.SchemeName, SchemeHandlerFactory = new CustomProtocolSchemeHandlerFactory(), IsCspBypassing = true // 关键配置:绕过CSP检查 }); settings.LogSeverity = LogSeverity.Default; Cef.Initialize(settings);
方案2:修改CSP规则,添加local:到允许列表
如果你不想绕过CSP,可以通过修改响应头的方式,把local:加入到object-src的允许列表中。你可以自定义一个RequestHandler来实现:
public class CustomRequestHandler : RequestHandler { protected override IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response) { var headers = response.Headers; const string cspKey = "Content-Security-Policy"; if (headers.ContainsKey(cspKey)) { // 在原CSP规则的object-src后追加local: string existingCsp = headers[cspKey]; headers[cspKey] = existingCsp.Replace("object-src *", "object-src * local:") ?? $"{existingCsp} object-src local:"; } else { // 如果没有CSP头,直接添加包含local:的规则 headers.Add(cspKey, "object-src * local: blob: externalfile: file: filesystem: data:"); } response.Headers = headers; return base.GetResourceResponseFilter(chromiumWebBrowser, browser, frame, request, response); } }
然后将这个Handler绑定到你的ChromiumWebBrowser实例:
var browser = new ChromiumWebBrowser("local://c/Users/abidh/Desktop/pdf.pdf"); browser.RequestHandler = new CustomRequestHandler();
额外说明
你之前尝试用ResourceHandler.FromFilePath依然无法显示,本质原因也是CSP拦截,和ResourceHandler的实现无关——只要解决了CSP问题,两种Handler写法都能正常工作。
内容的提问来源于stack exchange,提问作者Abid

