C#开发中WebBrowser控件的跨域问题使用实例

作者:小菜 更新时间:2025-03-16 点击数:
简介:我们在做web测试时,经常会使用WebBrowser来进行一些自动化的任务。

而有些网页上面会用IFrame去嵌套别的页面,这些页面可能不是在相同域名下的,这时就

【菜科解读】

我们在做web测试时,经常会使用WebBrowser来进行一些自动化的任务。

而有些网页上面会用IFrame去嵌套别的页面,这些页面可能不是在相同域名下的,这时就会出现跨域问题,无法直接在WebBrowser中获取到IFrame中的元素。

下面来做个试验,自己写个页面嵌套一个百度的首页,然后在我们自己的页面上输入要查询的词,最后在百度上自动完成搜索。

下面再建一个简单的WinForm工程测试一下,界面如下:

下面就是WebBrowser的测试代码:

using System;using System.Windows.Forms;namespace WebBrowserTest{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { this.webBrowser1.Navigate(this.textBox1.Text); } private void button2_Click(object sender, EventArgs e) { var doc = this.webBrowser1.Document; var frames = doc.Window.Frames; String testValue = doc.GetElementById("search").GetAttribute("value"); frames[0].Document.GetElementById("kw").SetAttribute("value", testValue); frames[0].Document.GetElementById("su").InvokeMember("click"); } }}

我们运行我们的测试程序后,加载之前我们自己写的页面后,在自己的页面上输入我们要查询的词,点击测试按钮,就会看到程序报未处理UnauthorizedAccessException错误:

下面来编写一个Helper类来解决这个问题,主要原理大致就是利用IWebBrowser2这个接口来获取Ifream中的Dom,IWebBrowser2中的document可以转换为IHtmlDocument1,IHtmlDocument2,IHtmlDocument3。

using System;using System.Runtime.InteropServices;using System.Windows.Forms;using mshtml;namespace WebBrowserTest{ // This is the COM IServiceProvider interface, not System.IServiceProvider .Net interface! [ComImport(), ComVisible(true), Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] public interface IServiceProvider { [return: MarshalAs(UnmanagedType.I4)] [PreserveSig] int QueryService(ref Guid guidService, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject); } public enum OLECMDF { OLECMDF_DEFHIDEONCTXTMENU = 0x20, OLECMDF_ENABLED = 2, OLECMDF_INVISIBLE = 0x10, OLECMDF_LATCHED = 4, OLECMDF_NINCHED = 8, OLECMDF_SUPPORTED = 1 } public enum OLECMDID { OLECMDID_PAGESETUP = 8, OLECMDID_PRINT = 6, OLECMDID_PRINTPREVIEW = 7, OLECMDID_PROPERTIES = 10, OLECMDID_SAVEAS = 4 } public enum OLECMDEXECOPT { OLECMDEXECOPT_DODEFAULT, OLECMDEXECOPT_PROMPTUSER, OLECMDEXECOPT_DONTPROMPTUSER, OLECMDEXECOPT_SHOWHELP } [ComImport, Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E"), TypeLibType(TypeLibTypeFlags.FOleAutomation | TypeLibTypeFlags.FDual | TypeLibTypeFlags.FHidden)] public interface IWebBrowser2 { [DispId(100)] void GoBack(); [DispId(0x65)] void GoForward(); [DispId(0x66)] void GoHome(); [DispId(0x67)] void GoSearch(); [DispId(0x68)] void Navigate([In] string Url, [In] ref object flags, [In] ref object targetFrameName, [In] ref object postData, [In] ref object headers); [DispId(-550)] void Refresh(); [DispId(0x69)] void Refresh2([In] ref object level); [DispId(0x6a)] void Stop(); [DispId(200)] object Application { [return: MarshalAs(UnmanagedType.IDispatch)] get; } [DispId(0xc9)] object Parent { [return: MarshalAs(UnmanagedType.IDispatch)] get; } [DispId(0xca)] object Container { [return: MarshalAs(UnmanagedType.IDispatch)] get; } [DispId(0xcb)] object Document { [return: MarshalAs(UnmanagedType.IDispatch)] get; } [DispId(0xcc)] bool TopLevelContainer { get; } [DispId(0xcd)] string Type { get; } [DispId(0xce)] int Left { get; set; } [DispId(0xcf)] int Top { get; set; } [DispId(0xd0)] int Width { get; set; } [DispId(0xd1)] int Height { get; set; } [DispId(210)] string LocationName { get; } [DispId(0xd3)] string LocationURL { get; } [DispId(0xd4)] bool Busy { get; } [DispId(300)] void Quit(); [DispId(0x12d)] void ClientToWindow(out int pcx, out int pcy); [DispId(0x12e)] void PutProperty([In] string property, [In] object vtValue); [DispId(0x12f)] object GetProperty([In] string property); [DispId(0)] string Name { get; } [DispId(-515)] int HWND { get; } [DispId(400)] string FullName { get; } [DispId(0x191)] string Path { get; } [DispId(0x192)] bool Visible { get; set; } [DispId(0x193)] bool StatusBar { get; set; } [DispId(0x194)] string StatusText { get; set; } [DispId(0x195)] int ToolBar { get; set; } [DispId(0x196)] bool MenuBar { get; set; } [DispId(0x197)] bool FullScreen { get; set; } [DispId(500)] void Navigate2([In] ref object URL, [In] ref object flags, [In] ref object targetFrameName, [In] ref object postData, [In] ref object headers); [DispId(0x1f5)] OLECMDF QueryStatusWB([In] OLECMDID cmdID); [DispId(0x1f6)] void ExecWB([In] OLECMDID cmdID, [In] OLECMDEXECOPT cmdexecopt, ref object pvaIn, IntPtr pvaOut); [DispId(0x1f7)] void ShowBrowserBar([In] ref object pvaClsid, [In] ref object pvarShow, [In] ref object pvarSize); [DispId(-525)] WebBrowserReadyState ReadyState { get; } [DispId(550)] bool Offline { get; set; } [DispId(0x227)] bool Silent { get; set; } [DispId(0x228)] bool RegisterAsBrowser { get; set; } [DispId(0x229)] bool RegisterAsDropTarget { get; set; } [DispId(0x22a)] bool TheaterMode { get; set; } [DispId(0x22b)] bool AddressBar { get; set; } [DispId(0x22c)] bool Resizable { get; set; } } class CorssDomainHelper { private static Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046"); private static Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E"); // Utility for IE cross domain access // Returns null in case of failure. public static IHTMLDocument3 GetDocumentFromWindow(IHTMLWindow2 htmlWindow) { if (htmlWindow == null) { return null; } // First try the usual way to get the document. try { IHTMLDocument2 doc = htmlWindow.document; return (IHTMLDocument3)doc; } catch (COMException comEx) { // I think COMException won't be ever fired but just to be sure ... } catch (UnauthorizedAccessException) { } catch (Exception ex) { return null; } // At this point the error was E_ACCESSDENIED because the frame contains a document from another domain. // IE tries to prevent a cross frame scripting security issue. try { // Convert IHTMLWindow2 to IWebBrowser2 using IServiceProvider. IServiceProvider sp = (IServiceProvider)htmlWindow; // Use IServiceProvider.QueryService to get IWebBrowser2 object. Object brws = null; sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out brws); // Get the document from IWebBrowser2. IWebBrowser2 browser = (IWebBrowser2)(brws); return (IHTMLDocument3)browser.Document; } catch (Exception ex) { Console.WriteLine(ex); } return null; } }}

最后将我们的运行代码改为如下形式,调用Helper类中的GetDocumentFromWindow方法:

using System;using System.Windows.Forms;using mshtml;namespace WebBrowserTest{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { this.webBrowser1.Navigate(this.textBox1.Text); } private void button2_Click(object sender, EventArgs e) { var doc = this.webBrowser1.Document; var frames = doc.Window.Frames; String testValue = doc.GetElementById("search").GetAttribute("value"); IHTMLDocument3 baiduDoc = CorssDomainHelper.GetDocumentFromWindow(frames[0].DomWindow as IHTMLWindow2); baiduDoc.getElementById("kw").setAttribute("value", testValue); baiduDoc.getElementById("su").click(); } }}

最后运行一下程序可以看到我们可以正常获取到百度上的元素了。

开发,中,WebBrowser,控件,的,跨域,问题,使用,

Win7电脑一按键盘U键就弹出轻松访问中心如何办?

想重装系统不会怎么办?菜科网一键重装系统轻松在线帮您搞定系统重装问题。

软件支持 在线重装、U盘制作、自定义重装 等多种模式。

有些用户发现:在Win7系统中只要按下键盘上的U键就会弹出控制面板的轻松访问中心界面,这是怎么回事呢?这个 轻松访问中心 是什么?其实,这个功能是一个给特殊人群准备的设置项,比如没有显示器,不用鼠标和键盘,是给眼障人士准备的。

那么,电脑一按键盘U键就弹出轻松访问中心该怎么办? 解决方法: 1、轻拍键盘或连续按Windows键看看能否解决问题; 2、实在不行可能需要更换键盘了! 3、Windows键(徽标键)和很多键位都有快捷键组合,如WIN+L键(锁屏),很容易判断是否WIN键粘住了! 4、取消轻松访问中心功能。

具体操作步骤如下: 进入控制面板,控制面板--轻松访问--轻松访问中心--管理设置,那个是不是勾选了?取消勾选,试试 另外你可以在控制面板中打开轻松访问,然后打开讲述人、设置对比度、筛选键等就那四个都重新设置一下,都把里面的勾给去掉就行了 关于Win7系统电脑一按键盘U键就会弹出轻松访问中心的解决方法小编就和大家介绍到这了,要是用户在使用电脑的过程中也遇到这问题的话可以参考本文介绍的方法来处理,希望可以帮助到大家。

电脑使用过程问题多?那就用菜科网软件,安装过程简单方便,系统稳定流畅。

注意:本站所刊载的文章均为学习交流之用,请勿用于商业用途。

对于商业使用,请联系各自版权所有者,否则法律问题自行承担。

Win7系统升级指南:全面解析升级步骤与要点 Win7系统损坏修复教程:详细步骤助你快速解决问题 Win7电脑一按键盘U键就弹出轻松访问中心怎么办? 分类于: 回答于:2016-03-09 有些用户发现:在Win7系统中只要按下键盘上的U键就会弹出控制面板的轻松访问中心界面,这是怎么回事呢?这个 轻松访问中心 是什么?其实,这个功能是一个给特殊人群准备的设置项,比如没有显示器,不用鼠标和键盘,是给眼障人士准备的。

那么,电脑一按键盘U键就弹出轻松访问中心该怎么办? 解决方法: 1、轻拍键盘或连续按Windows键看看能否解决问题; 2、实在不行可能需要更换键盘了! 3、Windows键(徽标键)和很多键位都有快捷键组合,如WIN+L键(锁屏),很容易判断是否WIN键粘住了! 4、取消轻松访问中心功能。

具体操作步骤如下: 进入控制面板,控制面板--轻松访问--轻松访问中心--管理设置,那个是不是勾选了?取消勾选,试试 另外你可以在控制面板中打开轻松访问,然后打开讲述人、设置对比度、筛选键等就那四个都重新设置一下,都把里面的勾给去掉就行了 关于Win7系统电脑一按键盘U键就会弹出轻松访问中心的解决方法小编就和大家介绍到这了,要是用户在使用电脑的过程中也遇到这问题的话可以参考本文介绍的方法来处理,希望可以帮助到大家。

电脑使用过程问题多?那就用菜科网软件,安装过程简单方便,系统稳定流畅。

菜科网系统致力于解决 Windows 系统重装解决方案,提供高效、安全、免费的系统重装服务。

盘点中国历史上七大忽悠,不作就不会死

在《庄子·应帝王第七》中,“忽”和“悠”分别是北海帝和南海帝的名字。

如今,忽悠是一个词,经由舞台演绎而成为流行语。

纵观中国历史,各个朝代都不乏忽悠人的事件,有的令人痛恨,有的令人叹惋,有的令人大笑,有的令人称颂,是是非非,纷纷扰扰。

最昂贵的忽悠:烽火示警 忽悠众诸侯 周幽王姬宫涅荒淫,对美人褒姒宠爱有加。

可是褒姒终日闷闷不乐,幽王悬赏道:能博美人一笑者赏千金。

有个叫虢石父的家伙出了个馊主意,幽王听后认为很棒,第二天,便带着褒姒上了骊山,把骊山上的烽火点燃。

诸侯们看见烽火燃起,以为犬戎入侵,赶紧领兵前来救驾。

褒姒看见骊山脚下兵马纷乱的样子,觉得很滑稽,不由得咧嘴一笑。

幽王见褒姒真的一展笑颜,立即赏给虢石父千金,而遭到忽悠的诸侯们则揣着一肚子怨气回到封地。

后来,犬戎真的进攻镐京,幽王下令点燃骊山烽火,可是诸侯们再也不尿他这一壶。

结果,犬戎兵到,镐京失守,褒姒被掳,幽王、虢石父被杀,平王继位,迁都洛邑,西周结束,东周肇始。

后人有诗云: 良夜颐宫奏管簧, 无端烽火烛穹苍。

可怜列国奔驰苦, 止博褒妃笑一场! 动用国防军事设施,调动诸侯兵马,仅为美人一笑,以至于国破身死,从“投入”与“收益”的比例来看,此忽悠的成本堪称历史最高了。

最阴险的忽悠: 赵忽悠 赵高曾为赵国贵族,亡国后被秦始皇阉割成为太监,骨子里恨死了秦始皇及其子孙。

秦二世时,赵高为架空皇权,便忽悠,说陛下年轻,又刚即位,如果在朝堂上现场处理政务,万一言语有误,将有损陛下圣明,所以,陛下不必临朝听政,只管深居宫禁,一切由我处理就行。

这话正中胡亥下怀,从此不理朝政。

赵高独揽大权,但他还想试探朝臣是否真心归附。

一天上朝时,赵高让人牵来一只鹿,对秦二世说:“陛下,我献给您一匹好马。

”秦二世说:“这是一只鹿,你怎么说是马呢?”赵高仍坚持说是马,并指着众大臣说:“陛下如果不信,可以问问他们。

” 大臣当中有几个据实说是鹿,但更多的人不敢实话实说,附和着赵高说是马。

胡亥闻言,,以为自己精神惑乱竞不辨鹿和马,于是就召来太仆占卦。

太仆得到赵高授意,便说胡亥在祭祀时没有严格遵守斋戒禁忌,所以神灵惑乱以至鹿马不分,必须严格行斋戒之礼。

这样的忽悠使胡亥,赶紧躲进上林苑,后来干脆跑到望夷宫避灾。

胡亥一走,赵高便把那些实话实说的大臣纷纷治罪。

此后,在赵高为非作歹之下,秦始皇一手缔造的迅速,赵高总算报了当年被阉之仇。

为了达到杀掉人家忠臣、毁掉人家江山的目的,赵高的忽悠真是歹毒之极。

最肉麻的忽悠:托梦邀宠 朱前疑忽悠 有一次,他上书武则天,忽悠道:“臣梦陛下寿满八百岁。

”武则天大喜,当即提拔他为拾遗。

不久,朱前疑又上奏:“臣梦陛下发白再黑,齿落更生。

”武则天又提升他为驾部郎中,掌管全国马驴牛羊及武则天出入的车乘驿马。

这还不算,还有一次,朱前疑出差回来,第三次上书武则天:“臣自河南返京,途经嵩山,闻见嵩山大呼陛下万岁,响彻云宵。

” 武则天闻言,嵩山乃五岳之首,如此良兆实为难得,于是赐给朱前疑一个绯算袋,按当时惯例,五品以上的朝臣才有资格佩戴,朱前疑获此殊荣,高兴万分。

然而,朱前疑贪心不足,后来又想故技重演捞实惠,结果竹篮打水一场空。

当时大唐出征契丹,下令京官每人捐一匹马,捐献者加封五品官。

朱前疑自认为官运又至,便买了一匹马捐出后,等待封官。

不过,这一次他失算了,捐马后很久都没有回音,朱前疑实在忍不住,就多次上书武则天要求提级。

武则天终于看清这个家伙的真实面目,认为他太过贪鄙,就命令退还他捐献的马,并将前面所赐官爵全部免掉,还强令他滚回老家。

武则天虽为帝王,但终归是女人,但凡女人都愿意别人夸其年轻漂亮,所以,再怎么肉麻的忽悠,女人都会笑纳。

再则,千万不可直接向女人讨要好处,因为除了青春之外,女人对财产同样敏感。

最搞笑的忽悠:蝗不食禾 京兆尹忽悠 蝗灾,是中国古代农业最主要的灾害之一,人们往往谈蝗色变,可是有个叫杨知至的家伙,偏偏以蝗求赏,着实把当朝忽悠了一把。

公元875年秋,大批蝗虫向京畿之地飞袭而来,遮天蔽日,所过之处,一切绿色植物瞬间被啃光。

然而,当时的京兆尹,也就是首都市长杨知至上奏朝廷说:这次蝗灾,波及全国,托皇上的恩庇,独京畿一带,蝗虫虽然也飞来了,但一只只都抱着荆棘,宁肯饿死也不吃田里的稼禾。

看到这样的奏折,唐僖宗高兴坏了。

那些大臣们不敢扫皇帝的兴,都,纷纷上殿道贺,歌颂皇帝英明圣德,将唐僖宗这个傻小子忽悠得心情爽极了,根本不知国祸之至。

蝗虫不吃庄稼,真亏杨知至想得出来,忽悠到这个份儿上,除了感觉滑稽好笑之外,真的是无话可说。

最死板的忽悠:刀枪不入 郭神仙忽悠 北宋靖康元年八月,金军对宋朝发动总攻,闰十一月杀到宋都开封城下。

这时,宋钦宗已经无将可用,正束手无策之际,郭京跑出来忽悠朝廷,声言自己会神术“六甲法”,可以把金军全部消灭,生擒敌军主帅。

所谓“六甲法”,就是选拔男子7779人,施行法咒后,刀枪不入。

宋钦宗听到奏报后,像抓到了救命稻草,马上给郭京封官,命他施法术与金军决战。

郭京施法的日子到了。

他命城上守军撤退,不准偷看,忽悠道:如果有谁偷看就会使神术失灵。

然后,他又命人打开城门,派七千多名所谓的神兵出击金兵。

结果,这些神兵非但不能保证刀枪不入,还被金兵杀得,如果不是守城的士兵紧急关闭城门,金军差点就乘势冲人。

见此情景,这个郭神仙再次忽悠道:看来还得由我亲自出城作法才行啊。

于是,他率领残余神兵,缒城而下。

不过,他没有冲向敌阵,而是头也不回地逃走了。

就在此时,金军猛烈攻城,城上没有守军,顷刻陷落,导致徽、钦二帝被俘,北宋落幕。

忽悠一下,弄点实惠,然后跑掉也就罢了,何苦要白白葬送七千之兵、满城之民、一国之君呢? 最无耻的忽悠:虚构战功 忽悠 公元1259年9月,忽必烈率领人马一路打到鄂州(今湖北武昌),宋理宗急忙命令四川宣抚使贾似道以“右丞相兼枢密使”的身份,屯兵汉阳以增援鄂州。

贾似道本是个不学无术之徒,同时也是个惜命怕死的家伙,不敢与蒙古军交兵,便地暗自遣使向忽必烈求和,擅自开出条件:宋朝向蒙古称臣,降为藩属;两国以长界,将江北土地全部割让;南宋每年向蒙古进贡银币20万两,绸缎20万匹。

当时,忽必烈正急于北返争斗大汗之位,便仓促接受了贾似道的条件,率军北还。

贾似道立即叛盟,下令截杀蒙古负责殿后的散兵游勇,用他们的人头,作为辉煌战果的证据,向宋理宗报捷,地忽悠道:“诸路大捷,鄂围始解,江汉肃清,宗社危而复安,实之休!” 宋理宗,为贾似道举行了盛大的欢迎仪式。

后来,蒙古派人找到贾似道要求兑现当年的合约,贾似道将使者秘密囚禁,以至于全国都没有人知道他私自求和的事情。

从此,贾似道被宋理宗视作“王室有同于再造”的大救星。

这一切都为他后来独揽朝政奠定了基础。

卑鄙是卑鄙者的通行证,当代著名诗人北岛的这句诗是整个事件的最好注脚。

最神奇的忽悠:海上寻仙 徐方士忽悠秦始皇 公元前219年,秦始皇乘兴东巡,到达琅邪。

琅邪郡有个方士叫徐福,上书秦始皇,称海中有蓬莱、方丈、瀛洲三座神山,是仙人居所。

秦始皇,征集数千名男女,让徐福率领到海中求仙。

不料,一去数年终无所获。

徐福便再次上书,继续忽悠秦始皇,说蓬莱神山之药,本来唾手可得,只是海中大鲛鱼常阻碍船队行进,请陛下派遣神射手和我一同人海,用连弩射杀鲛鱼。

刚巧秦始皇曾梦见与海神作战,占梦博士的解说和徐福的说法竟然十分吻合,秦始皇又一次深信不疑,于是命令人海船队配备捕捉大鱼的工具,亲自率领连弩射手寻找大鲛,直到之罘(烟台)才见到一只,便用连弩射杀。

在返回途中,秦始皇身染重病,不久在河北沙丘驾崩,他延年益寿的幻想终成泡影。

而徐福则在齐郡黄县一带,筹集五谷、百工及数千名童男童女,扬帆东渡,一去不返。

有神山,有仙人,有大鲛,有海神,方士徐福的忽悠真是神奇到家了,如今的《哈利·波特》也不过如此。

随机文章最紧张的高空定点跳伞,英国狂人开伞慢1秒险摔死女孩学心理学的坏处,学心理学的女孩不好找男朋友/智商太高带土召唤外道魔像,揭秘宇智波带土会什么忍术宇航员在太空会遇到什么危险,陨石撞击/航天器破损失压/宇宙辐射蓝色皮肤的奥坎基查尔族人,堪比外星人/科学家至今找不出原因

加入收藏
               

C#开发中WebBrowser控件的跨域问题使用实例

点击下载文档

格式为doc格式

  • 账号登录
社交账号登录