向Webbrowser控件添加针对C#中所有请求的自定义标头? [英] Add a customized header to Webbrowser control for all requests in C#?

查看:419
本文介绍了向Webbrowser控件添加针对C#中所有请求的自定义标头?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C#和.NET 3.5.如您所知,我们可以向Web浏览器控件上的Navigate()添加自定义标头,如下所示:

I'm using C# and .NET 3.5. As you know, we can add custom header to Navigate() on the web browser control like this:

var myUrl = "http://example.com/mypage.htm";
System.Uri uri = new Uri(myUrl);

byte[] authData = System.Text.UnicodeEncoding.UTF8.GetBytes("user:password");
string authHeader = 
    "Authorization: Basic " + Convert.ToBase64String(authData) + "\r\n" +
    "User-Agent: MyUserAgent\r\n";

webTDW8961nd.Navigate(uri, "", null, authHeader);

在上面的示例中,我们为单个导航设置了基本授权"标头.

In the example above we set a Basic Authorization header for a single navigation.

现在让我们谈谈重定向.如果我们要执行将重定向到另一个页面的javascript,则不会包含基本授权"标头.

Now let talk about redirection. If we want to execute javascript which will redirect to another page, the Basic Authorization header won't be included.

您的解决方案是什么?如何添加适用于所有请求的标头,而不仅适用于一次?

What is your solution? How can I add a header which works for all of the requests and not only once?

推荐答案

问题是,尽管WinForm和WPF的WebBrowser只是ActiveX IE控件的一个相对较薄的包装,但它们并没有公开所有我们感兴趣的事件(第二个事件比第一个事件少).解决此问题的方法有两种:首先,将WF浏览器控件子类化并添加所需的内容,或者使用WPF控件并在其中添加钩子.我发现第二种方法在WPF应用程序中更方便.

The problem is that while both WinForm's and WPF's WebBrowser are nothing else but a relatively thin wrapper around the ActiveX IE control, they don't expose all the events of interest to us (and the second provides even less than the first). There are two ways to solve this: first, to subclass the WF browser control and add what you need or to use the WPF one and add the hooks there. I found the second approach to be more convenient in a WPF application.

您只需要相关的界面.最简单的方法是添加对 Microsoft Internet Controls 的引用(您会在COM标题下找到VS).这样会打开一个名为SHDocVw的命名空间,其中包含我们需要的所有内容(如果出于某种原因想要摆脱这种依赖关系,则可以简单地将使用的P/Invoke接口复制到自己的代码中.)

You only need the relevant interfaces. The easiest way is to add a reference to Microsoft Internet Controls (you'll find this under the COM heading is VS). This opens up a namespace called SHDocVw that contains all we need (if, for any reason, you want to get rid of this dependency, you can simply copy the P/Invoke interfaces used into your own code).

您可以使用反射来获得基础浏览器.如果调用得太早,它将返回null,因此我将其放入WebBrowser.Navigating处理程序中:

You can get the underlying browser using reflection. It will return null if you call it too early, so I put it into the WebBrowser.Navigating handler:

using SHDocVw;
var ActiveXInstance = (IWebBrowser2)Browser.GetType().InvokeMember("ActiveXInstance", BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic, null, Browser, new object[] { });

拥有它后,就可以使用浏览器完成一些不错的工作.例如,您可以使用不直接公开的各种属性和方法:

As soon as you have it, you can do nice things with the browser. For instance, you can use various properties and methods not exposed directly:

ActiveXInstance.Silent = true; // suppresses script error dialogs

并添加缺少的事件挂钩:

and add the missing event hooks:

var SetupEvents2 = (DWebBrowserEvents2_Event)ActiveXInstance;
SetupEvents2.BeforeNavigate2 += OnBeforeNavigate2;

有两个事件接口,2变体包含较新的事件.您可以在 MSDN上查找所有内容.

There are two event interfaces, the 2 variant contains the newer events. You can look all this up on MSDN.

然后,返回标题:BeforeNavigate2事件允许您将多余的标题放入提供的对象中:

And, back to the headers: the BeforeNavigate2 event allows you to put your extra headers into the provided object:

private void OnBeforeNavigate2(object pDisp, ref object URL, ref object Flags, ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel) {
  Headers = $"Accept-Language: XX;en\r\n";
}

这篇关于向Webbrowser控件添加针对C#中所有请求的自定义标头?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆