Add a customized header to WebBrowser control for all requests in C++/CLI?

▼魔方 西西 提交于 2019-12-08 05:40:22

问题


I'm trying to reproduce this C# workaround in C++/CLI, but it doesn't work, here's my code:

private: System::Void WebBrowser1_Navigating(System::Object^ sender, System::Windows::Forms::WebBrowserNavigatingEventArgs^ e) {
    System::Diagnostics::Debug::WriteLine("Running...");
    auto activeXInstance = (SHDocVw::IWebBrowser2^) this->webBrowser1->GetType()->InvokeMember("ActiveXInstance", System::Reflection::BindingFlags::GetProperty | System::Reflection::BindingFlags::Instance | System::Reflection::BindingFlags::NonPublic, nullptr, this->webBrowser1, gcnew array<System::Object^>{});
    System::Diagnostics::Debug::WriteLine("I won't be printed.");
    auto setupEvents2 = (SHDocVw::DWebBrowserEvents2_Event^) activeXInstance;
    setupEvents2->BeforeNavigate2 += gcnew SHDocVw::DWebBrowserEvents2_BeforeNavigate2EventHandler(this, &MyForm::OnBeforeNavigate2);
}

private: System::Void OnBeforeNavigate2(System::Object^ pDisp, System::Object^% URL, System::Object^% Flags, System::Object^% TargetFrameName, System::Object^% PostData, System::Object^% Headers, bool %Cancel) {
    Headers = "User-Agent:Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19";
}

That method is executed however it stops at the first line, the next lines get capped and no exceptions are thrown.


回答1:


This is how I solved the problem in C#:

  • Added a reference to SHDocVw. You can find SHDocVw as "Microsoft Internet Controls" in COM tab of Reference manager window.
  • Browse about:blank *Subscribed to BeforeNavigate2 event of DWebBrowserEvents2_Event. I got the instance of the interface from webBrowser1.ActiveXInstance.
  • In BeforeNavigate2 event handler, I check if the header in which I'm interested, doesn't exists in the headers, and if the URL is a http or https URL (and for example is not a javascript: url) and if the request is not for an iframe, then I stop the request and send the request with new headers.

Here is the code which worked for me as expected:

string additionalHeader = "User-Agent:Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; " +
    "Microsoft; Lumia 950 XL Dual SIM) AppleWebKit/537.36 (KHTML, like Gecko) " +
    "Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.15063\r\n";
private void Form1_Load(object sender, EventArgs e)
{
    webBrowser1.ScriptErrorsSuppressed = true;
    webBrowser1.Navigate("about:blank", null, null, additionalHeader);
    var wbevents = (DWebBrowserEvents2_Event)webBrowser1.ActiveXInstance;
    wbevents.BeforeNavigate2 += Wbevents_BeforeNavigate2;
    webBrowser1.Navigate("http://google.com", null, null, additionalHeader);
}

private void Wbevents_BeforeNavigate2(object pDisp, ref object URL, ref object Flags,
    ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel)
{
    if (!$"{Headers}".Contains(additionalHeader) &&
        TargetFrameName == null &&
        $"{URL}".ToLower().StartsWith("http"))
    {
        Cancel = true;
        ((IWebBrowser2)pDisp).Stop();
        object headers = additionalHeader + $"{Headers}";
        object url = $"{URL}";
        object flags = null;
        object targetFrameName = $"{TargetFrameName}";
        ((IWebBrowser2)pDisp).Navigate2(ref url, ref flags,
            ref targetFrameName, ref PostData, ref headers);
    }
}

Note 1 - Navigating will not raise on Refresh

There is a feature/flaw in browser with refresh. When you refresh the browser, Navigating event will not raise, which means the header will not be added in case of refresh. A workaround for that is disabling shortcut and context menu:

this.webBrowser1.WebBrowserShortcutsEnabled = false;
this.webBrowser1.IsWebBrowserContextMenuEnabled = false;

Note 2 - Set user agent

Since this question is about adding header for user agent, there is a better solution for that. You can use the solution which is shared at bottom of this post: Winform Webbrowser being recognized as a mobile device.

It works well even when you refresh the browser.



来源:https://stackoverflow.com/questions/57361094/add-a-customized-header-to-webbrowser-control-for-all-requests-in-c-cli

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!