提问人:John Saunders 提问时间:3/11/2014 更新时间:3/24/2018 访问量:2918
当页面重定向到 localhost 时未引发导航事件
Navigating Event Not Raised when a Page Redirects to localhost
问:
我有一个使用 OAUTH 服务的 Windows 窗体应用程序。为了进行身份验证,我使用 Web 浏览器控件导航到服务的登录页面。用户输入用户名和密码,效果很好。
接下来,该服务将显示“授予访问权限”页面。当用户单击“授予访问权限”时,页面将重定向到我选择的 URL,并在查询字符串中传递身份验证令牌。
这在我开发的 Windows 7 机器上运行良好。我在 Navigating 事件中捕获查询字符串,隐藏 Web 浏览器控件,然后可以使用我收到的令牌来使用该服务。但在 Windows 8 和 Windows Server 2012 上,导航事件永远不会发生。相反,Web 浏览器控件显示 404 错误。
有没有办法捕获该重定向的结果?
P.S. 我尝试使用 HttpListener,它起作用了,但它需要管理员安装应用程序来设置 http 绑定。
答:
2赞
noseratio
3/11/2014
#1
尝试在基础 ActiveX 上处理原始 BeforeNavigate2
事件,下面是 WinForms 版本(基于原始 WPF 版本):WebBrowser
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsForms_22311110
{
public partial class MainForm : Form
{
WebBrowser webBrowser;
public MainForm()
{
InitializeComponent();
this.webBrowser = new WebBrowser();
this.webBrowser.Dock = DockStyle.Fill;
this.Controls.Add(this.webBrowser);
this.webBrowser.Visible = true;
this.Load += MainForm_Load;
}
void MainForm_Load(object sender, EventArgs e)
{
// the below line makes sure the underlying ActiveX gets created
if (this.webBrowser.Document != null || this.webBrowser.ActiveXInstance == null)
throw new InvalidOperationException("webBrowser");
var sink = new WebBrowserEventSink();
sink.Connect(this.webBrowser);
this.webBrowser.Navigate("http://example.com");
}
}
/// <summary>
/// Handling WinForms WebBrowser ActiveX events directly
/// this code depends on SHDocVw.dll COM interop assembly,
/// generate SHDocVw.dll: "tlbimp.exe ieframe.dll",
/// and add as a reference to the project
///
/// by Noseratio - https://stackoverflow.com/a/22312476/1768303
/// </summary>
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(SHDocVw.DWebBrowserEvents2))]
public class WebBrowserEventSink : SHDocVw.DWebBrowserEvents2
{
System.Runtime.InteropServices.ComTypes.IConnectionPoint _sinkCP = null;
int _sinkCookie = int.MaxValue;
public void Connect(WebBrowser webBrowser)
{
if (_sinkCookie != int.MaxValue)
throw new InvalidOperationException();
var activeXInstance = webBrowser.ActiveXInstance;
var cpc = (System.Runtime.InteropServices.ComTypes.IConnectionPointContainer)activeXInstance;
var guid = typeof(SHDocVw.DWebBrowserEvents2).GUID;
cpc.FindConnectionPoint(ref guid, out _sinkCP);
_sinkCP.Advise(this, out _sinkCookie);
}
public void Disconnect()
{
if (_sinkCookie == int.MaxValue)
throw new InvalidOperationException();
_sinkCP.Unadvise(_sinkCookie);
_sinkCookie = int.MaxValue;
_sinkCP = null;
}
#region SHDocVw.DWebBrowserEvents2
public void StatusTextChange(string Text)
{
}
public void ProgressChange(int Progress, int ProgressMax)
{
}
public void CommandStateChange(int Command, bool Enable)
{
}
public void DownloadBegin()
{
}
public void DownloadComplete()
{
}
public void TitleChange(string Text)
{
}
public void PropertyChange(string szProperty)
{
}
public void BeforeNavigate2(object pDisp, ref object URL, ref object Flags, ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel)
{
MessageBox.Show("BeforeNavigate2: " + URL.ToString());
}
public void NewWindow2(ref object ppDisp, ref bool Cancel)
{
}
public void NavigateComplete2(object pDisp, ref object URL)
{
}
public void DocumentComplete(object pDisp, ref object URL)
{
}
public void OnQuit()
{
}
public void OnVisible(bool Visible)
{
}
public void OnToolBar(bool ToolBar)
{
}
public void OnMenuBar(bool MenuBar)
{
}
public void OnStatusBar(bool StatusBar)
{
}
public void OnFullScreen(bool FullScreen)
{
}
public void OnTheaterMode(bool TheaterMode)
{
}
public void WindowSetResizable(bool Resizable)
{
}
public void WindowSetLeft(int Left)
{
}
public void WindowSetTop(int Top)
{
}
public void WindowSetWidth(int Width)
{
}
public void WindowSetHeight(int Height)
{
}
public void WindowClosing(bool IsChildWindow, ref bool Cancel)
{
}
public void ClientToHostWindow(ref int CX, ref int CY)
{
}
public void SetSecureLockIcon(int SecureLockIcon)
{
}
public void FileDownload(bool ActiveDocument, ref bool Cancel)
{
}
public void NavigateError(object pDisp, ref object URL, ref object Frame, ref object StatusCode, ref bool Cancel)
{
}
public void PrintTemplateInstantiation(object pDisp)
{
}
public void PrintTemplateTeardown(object pDisp)
{
}
public void UpdatePageStatus(object pDisp, ref object nPage, ref object fDone)
{
}
public void PrivacyImpactedStateChange(bool bImpacted)
{
}
public void NewWindow3(ref object ppDisp, ref bool Cancel, uint dwFlags, string bstrUrlContext, string bstrUrl)
{
}
public void SetPhishingFilterStatus(int PhishingFilterStatus)
{
}
public void WindowStateChanged(uint dwWindowStateFlags, uint dwValidFlagsMask)
{
}
public void NewProcess(int lCauseFlag, object pWB2, ref bool Cancel)
{
}
public void ThirdPartyUrlBlocked(ref object URL, uint dwCount)
{
}
public void RedirectXDomainBlocked(object pDisp, ref object StartURL, ref object RedirectURL, ref object Frame, ref object StatusCode)
{
}
public void BeforeScriptExecute(object pDispWindow)
{
}
public void WebWorkerStarted(uint dwUniqueID, string bstrWorkerLabel)
{
}
public void WebWorkerFinsihed(uint dwUniqueID)
{
}
#endregion
}
}
评论
0赞
John Saunders
3/11/2014
我相信这会奏效的。事实上,它向我表明我正在接收一个事件。它只是没有告诉我为什么。我需要尝试观看网络,但 1) 当我使用 Fiddler 时,整个过程都正常,并且 2) 通信是通过 SSL 进行的。我知道“当我使用 Fiddler 时它有效”通常意味着代理问题,但我的(家庭)网络上没有代理服务器。NavigationError
0赞
noseratio
3/11/2014
@JohnSaunders,您的国际空间站上是否安装了合法的SSL证书?当您在 IE 中拨打相同的 URL 时,完整的 IE 浏览器不会抱怨什么?
0赞
John Saunders
3/11/2014
它不是我的 IIS 服务器。这是一个商业网站。
0赞
noseratio
3/11/2014
@JohnSaunders,如果您愿意进一步尝试,请尝试实现 IHttpSecurity
服务。有一个快捷方式可以通过 IProfferService
执行此操作。
1赞
John Saunders
3/11/2014
我之所以能够猜到这一点,是因为我上了 URL,这应该会导致重定向到我的回调地址。但肯定应该有更明确的迹象吗?我浪费了几个星期的时间,却看不到发生了什么!NavigateError
评论
BeforeNavigate2