WatiN浏览器中的自定义BeforeNavigate事件

5
我试图使用WatiN框架通过在“before navigation”事件中修改头文件来更改用户代理字符串。我认为我已经非常接近解决方案了,但出现以下代码后,几秒钟后URL被访问后,我不知何故会被重定向到一个空白页面。
如果我注释掉自定义的BeforeNavigate事件,浏览器就不会重定向到空白页面,这导致我相信我的自定义事件需要做一些微小的修改。您有什么想法可能是问题所在吗?
要复制此问题,请下载WatiN并运行以下代码:
private SHDocVw.InternetExplorerClass _ieInstance;

private const string UserAgent = 
   "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64)" +
    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153" + 
    "Safari/537.36\r\n";

bool _renavigating;
private IE _browser;

private void Form1_Load(object sender, EventArgs e)
{
    _ieInstance = _ieInstance = new SHDocVw.InternetExplorerClass();
    //_ieInstance.BeforeNavigate2 += BeforeNavigate;
    _browser = new IE(_ieInstance);
    _browser.GoTo("http://www.procato.com/my+headers/");
}

void BeforeNavigate(object pDisp, ref object url, ref object flags, 
     ref object targetFrameName, ref object postData, ref object headers, 
     ref bool cancel)
{
    if (!string.IsNullOrEmpty(UserAgent))
    {
        if (!_renavigating)
        {
            headers += string.Format("User-Agent: {0}\r\n", UserAgent);
            _renavigating = true;
            cancel = true;
            _ieInstance.Navigate((string)url, 
                 (string)targetFrameName, (byte[])postData, (string)headers);
        }
        else
        {
            _renavigating = false;
        }
    }
}

@Noseratio的建议也给我留下了一个空白页面:
readonly SynchronizationContext _sc = SynchronizationContext.Current;

void BeforeNavigate(object pDisp, ref object url, ref object flags, 
     ref object targetFrameName, ref object postData, ref object headers, 
     ref bool cancel)
{
    if (!string.IsNullOrEmpty(UserAgent))
    {
        if (!_renavigating)
        {
            var newHeaders = string.Format("User-Agent: {0}\r\n", UserAgent);
            _renavigating = true;
            cancel = true;

            string thatUrl = (string)url;
            object thatFlags = flags;
            object thatTargetFrameName = targetFrameName;
            object thatPostData = postData;
            object thatHeaders = (headers != null && headers != Type.Missing && 
                               headers != System.DBNull.Value) ?
                (headers.ToString() + newHeaders) : newHeaders;

            _sc.Post(_ => 
            { 
                ((SHDocVw.IWebBrowser)pDisp).Navigate(
                    thatUrl, 
                    ref thatFlags,
                    ref thatTargetFrameName,
                    ref thatPostData,
                    ref thatHeaders);
            }, null);
        }
        else
        {
            _renavigating = false;
        }
    }
}

您需要在所有请求中更改用户代理,还是仅在直接导航到页面的请求中更改即可?此外,在单个测试/进程中,您是否需要多次将其更改为不同的内容? - Ben Aaronson
@BenAaronson 抱歉,由于某些原因我没有收到这个通知。导航到页面的请求就足够了。是的,每个“IE”实例都需要能够拥有自己的标头。 - Johan
1个回答

0

请求导航到页面就足够了。

在这种情况下,我建议您通过放弃 BeforeNavigate2,并简单地使用 _ieInstance.Navigate 进行导航,从而使您的生活更加简单。例如:

private void Form1_Load(object sender, EventArgs e)
{
    _ieInstance = _ieInstance = new SHDocVw.InternetExplorerClass();
    _browser = new IE(_ieInstance);
    _ieInstance.Navigate("http://www.procato.com/my+headers/", Headers: UserAgent);
}

在 procato 上显示的结果将是错误的标头,因为加载页面会发出其他请求,而这些请求不会具有正确的标头。但是,如果您使用像 Fiddler2 这样的工具,您将看到初始请求具有正确的用户代理标头。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接