【问题标题】:chromium - send custom header info on initial page load c#chromium - 在初始页面加载 c# 时发送自定义标题信息
【发布时间】:2015-09-23 21:24:33
【问题描述】:

在新建 ChromiumWebBrowser 实例时如何将自定义标头注入到网站的初始请求中。

我是 Chromium 的菜鸟,真的需要一些帮助。我有一个带有 CEF 窗口的 winforms 应用程序。 K,目前还没有问题。我需要做的是使用包含身份验证信息的自定义 http-header 调用/加载初始 url。这可能吗?

以下内容基本上是在发挥作用,所有部分都可以正常工作,除了自定义标题(Doh!)

Winform(CEF httpRequest(with custom header)) [永远不会超过这一点]=> C# MVC web 应用程序 => Owin_Authentication_Pipeline 段 => 填充 Razor 视图的 MVC 响应 => 显示在 Winform Chromium 应用程序中。

也许这也会有所帮助:

using CefSharp;
using CefSharp.WinForms;
...
private void Form1_Load(object sender, EventArgs e)
{
    Cef.Initialize();
    ChromiumWebBrowser myBrowser = new ChromiumWebBrowser("whatever.com");
    // ??How do i get a custom header be sent with the above line??

    myBrowser.Dock = DockStyle.Fill;
    //myBrowser.ShowDevTools();
    //myBrowser.RequestHandler = new DSRequestHander();
    //myBrowser.FrameLoadStart += myBrowser_FrameLoadStart;
    this.Controls.Add(myBrowser);
}

我把这个弄死了,看了看,尝试了我工具箱中的所有技巧,然后又尝试了一些。

非常感谢任何关于我如何能够解决或绕过这个令人困惑的想法、帮助或提示。提前致谢。

【问题讨论】:

  • 您在使用 CEFSharp 项目吗? github.com/cefsharp/CefSharp/wiki
  • @NinjaMid76 是的,我是。
  • 如果你不分享更多信息,几乎不可能帮助你。关于您的自定义标头在这个组件链中的位置。它是否出现在 Owin_Authentication_Pipeline 段中?它拒绝它吗?等等等等。向我们提供一些您尝试过的基本调试信息。好的stackoverflow问题有MVCE
  • @jornh ..chill。没有必要诋毁。 “不”它没有到达 owin 管道。问题是如何在新建 ChromiumWebBrowser 时将自定义标头注入到对站点的初始请求中。我已经编辑了这个问题以澄清。感谢您的反馈。干杯...一切都很好。
  • 无意诋毁 - 只是想尽可能多地进行猜测以便更好地提供帮助:-)。您的编辑对此有很大帮助!您是否尝试过类似groups.google.com/forum/m/#!topic/cefsharp/Yi9bWHmASQU 的方法?那篇文章现在有点过时了,不确定 API 从那时起是否发生了变化。

标签: c# winforms chromium-embedded cefsharp custom-headers


【解决方案1】:

更新以反映 Chromium 的主要变化

已更新以反映版本 75 中所做的更改(应该适用于 75 和更高版本)

你所追求的方法应该是OnBeforeResourceLoad,一个基本的例子应该是这样的:

public class CustomResourceRequestHandler : ResourceRequestHandler
{
    protected override CefReturnValue OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
    {
        var headers = request.Headers;
        headers["User-Agent"] = "My User Agent";
        request.Headers = headers;

        return CefReturnValue.Continue;
    }
}

public class CustomRequestHandler : RequestHandler
{
    protected override IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
    {
        return new CustomResourceRequestHandler();
    }
}

browser.RequestHandler = new CustomRequestHandler();

使用 IRequest.Headers 属性,您必须阅读 headers 属性,进行更改然后重新分配它。现在可以使用SetHeaderByName/GetHeaderByName 函数来获取/设置单个标头。

【讨论】:

  • 我创建了一个继承自 ChromiumWebBrowser 的 CustomChromeBrowser 类,并通过 CustomChromeBrowser 类的 Initialized 事件分配了一个 RequestHandler 类(带有演示项目)。
  • 所有Handlers 都是简单的属性,在构造函数中赋值就足够了。
  • 能否提供更多详细信息,我也遇到了同样的问题,但我不确定如何按照您的建议进行操作。
  • 所有与浏览器直接相关的请求都应该流经这里。您可以使用 cefsharp.github.io/api/81.3.x/html/… 进行 RequestContext 级别的处理。如果您在仅隔离 Ajax 请求时遇到问题,请提出一个新问题。
  • 请参阅 github.com/cefsharp/CefSharp/wiki/… 了解 RequestContext 的背景详细信息。来自 Service Worker 的内存请求只能通过 RequestContext 级别的处理来访问,因为它们不一定与浏览器直接关联。
【解决方案2】:

您应该创建一个实现IRequestHandler 的类,然后在您的浏览器对象中将该类的实例设置为RequestHandler

对于 53 版,该类应如下所示:

class ChromeBrowserRequestHandler: IRequestHandler
    {
        public bool GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
        {
            return false;
        }

        public bool OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool isRedirect)
        {
            return false;
        }

        public bool OnBeforePluginLoad(IWebBrowser browser, string url, string policyUrl, WebPluginInfo info)
        {
            return false;
        }

        public CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
        {
            var headers = request.Headers;
            headers["Custom-Header"] = "My Custom Header";
            request.Headers = headers;

            return CefReturnValue.Continue;
        }

        public bool OnCertificateError(IWebBrowser browser, CefErrorCode errorCode, string requestUrl)
        {
            return false;
        }

        public void OnPluginCrashed(IWebBrowser browser, string pluginPath)
        {
        }

        public void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status)
        {
        }

        public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) 
        { 
            return null; 
        }

        public bool OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback) 
        {
            return false; 
        }

        public bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture) 
        {
            return false; 
        }

        public void OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath) 
        {
        }

        public bool OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url) 
        {
            return false;
        }

        public bool OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl, long newSize, IRequestCallback callback) 
        {
            return false;
        }

        public void OnRenderViewReady(IWebBrowser browserControl, IBrowser browser) 
        { 
        }

        public void OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
        { 
        }

        public void OnResourceRedirect(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, ref string newUrl) 
        { 
        }

        public bool OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) 
        {
            return false;
        }
    }

然后,在创建浏览器对象时:

ChromiumWebBrowser myBrowser = new ChromiumWebBrowser("whatever.com")
{
    RequestHandler = new ChromeBrowserRequestHandler()
};

请注意,请求处理程序必须在加载页面之前设置。如果您在实例化过程中无法设置请求处理程序,您仍然可以稍后设置它并使用 myBrowser.Load("whatever.com") 重新加载页面。

【讨论】:

  • 使用版本 47.0.2.0,我没有看到开发工具中的请求标头有任何变化。
【解决方案3】:

在最新版本之一中,一些回调已从IRequestHandler 移至IResourceRequestHandler 接口。最简单的方法是覆盖默认实现RequestHandler & ResourceRequestHandler,例如:

class BearerAuthResourceRequestHandler : ResourceRequestHandler
    {
        public BearerAuthResourceRequestHandler(string token)
        {
            _token = token;
        }

        private string _token;

        protected override CefReturnValue OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
        {
            if (!string.IsNullOrEmpty(_token))
            {
                var headers = request.Headers;
                headers["Authorization"] = $"Bearer {_token}";
                request.Headers = headers;
                return CefReturnValue.Continue;
            }
            else return base.OnBeforeResourceLoad(chromiumWebBrowser, browser, frame, request, callback);
        }

    }
    class BearerAuthRequestHandler : RequestHandler
    {
        public BearerAuthRequestHandler(string token)
        {
            _token = token;
        }

        private string _token;

        protected override IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
        {
            if (!string.IsNullOrEmpty(_token)) return new BearerAuthResourceRequestHandler(_token);
            else return base.GetResourceRequestHandler(chromiumWebBrowser, browser, frame, request, isNavigation, isDownload, requestInitiator, ref disableDefaultHandling);
        }
    }

然后,将其分配给浏览器RequestHandler

Browser.RequestHandler = new BearerAuthRequestHandler(token);

【讨论】:

    猜你喜欢
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 2023-01-16
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    相关资源
    最近更新 更多