Как внедрить Javascript в элемент управления WebBrowser?
Я попытался это:
string newScript = textBox1.Text;
HtmlElement head = browserCtrl.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = browserCtrl.Document.CreateElement("script");
lblStatus.Text = scriptEl.GetType().ToString();
scriptEl.SetAttribute("type", "text/javascript");
head.AppendChild(scriptEl);
scriptEl.InnerHtml = "function sayHello() { alert('hello') }";
scriptEl.InnerHTML и scriptEl.Внутренний текст оба дают ошибки:
System.NotSupportedException: Property is not supported on this type of HtmlElement.
at System.Windows.Forms.HtmlElement.set_InnerHtml(String value)
at SForceApp.Form1.button1_Click(Object sender, EventArgs e) in d:jsightinstallsSForceAppSForceAppForm1.cs:line 31
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
есть ли простой способ ввести скрипт в dom?
15 ответов:
по какой-то причине решение Ричарда не сработало на моем конце (insertAdjacentText не удалось с исключением). Это, однако, кажется, работает:
HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0]; HtmlElement scriptEl = webBrowser1.Document.CreateElement("script"); IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement; element.text = "function sayHello() { alert('hello') }"; head.AppendChild(scriptEl); webBrowser1.Document.InvokeScript("sayHello");ответ объясняет, как получить
IHTMLScriptElementинтерфейс в ваш проект.
HtmlDocument doc = browser.Document; HtmlElement head = doc.GetElementsByTagName("head")[0]; HtmlElement s = doc.CreateElement("script"); s.SetAttribute("text","function sayHello() { alert('hello'); }"); head.AppendChild(s); browser.Document.InvokeScript("sayHello");(протестировано в приложении .NET 4 / Windows Forms)
Edit: Исправлена проблема случая в наборе функций.
вот самый простой способ, который я нашел после работы над этим:
string javascript = "alert('Hello');"; // or any combination of your JavaScript commands // (including function calls, variables... etc) // WebBrowser webBrowser1 is what you are using for your web browser webBrowser1.Document.InvokeScript("eval", new object[] { javascript });какая глобальная функция JavaScript
eval(str)делает это анализирует и выполняет все, что написано в str. Проверьте w3schools Реф.
кроме того, в .NET 4 это еще проще, если вы используете динамическое ключевое слово:
dynamic document = this.browser.Document; dynamic head = document.GetElementsByTagName("head")[0]; dynamic scriptEl = document.CreateElement("script"); scriptEl.text = ...; head.AppendChild(scriptEl);
Если все, что вы действительно хотите, это запустить javascript, это было бы проще всего (VB .Net):
MyWebBrowser.Navigate("javascript:function foo(){alert('hello');}foo();")Я думаю, что это не будет "вводить" его, но он будет запускать вашу функцию, если это то, что вам нужно. (На случай, если вы слишком усложнили задачу.) И если вы можете выяснить, как вводить в javascript, поместите это в тело функции "foo" и пусть javascript сделает инъекцию для вас.
управляемая оболочка для HTML-документа не полностью реализует необходимую вам функциональность, поэтому вам нужно окунуться в API MSHTML, чтобы выполнить то, что вы хотите:
1) добавьте ссылку на MSHTML, которая будет probalby называться "Microsoft HTML Object Library" под COM ссылки.
2) Добавьте 'using mshtml;' к вашим пространствам имен.
3) получить ссылку на IHTMLElement элемент скрипта:
IHTMLElement iScriptEl = (IHTMLElement)scriptEl.DomElement;4) назвать метод insertAdjacentText, с первым значением параметра "afterBegin". Все возможные значения перечислены здесь:
iScriptEl.insertAdjacentText("afterBegin", "function sayHello() { alert('hello') }");5) Теперь вы сможете посмотреть код в scriptEl.InnerText свойство.
Hth, Ричард
это решение с использованием mshtml
IHTMLDocument2 doc = new HTMLDocumentClass(); doc.write(new object[] { File.ReadAllText(filePath) }); doc.close(); IHTMLElement head = (IHTMLElement)((IHTMLElementCollection)doc.all.tags("head")).item(null, 0); IHTMLScriptElement scriptObject = (IHTMLScriptElement)doc.createElement("script"); scriptObject.type = @"text/javascript"; scriptObject.text = @"function btn1_OnClick(str){ alert('you clicked' + str); }"; ((HTMLHeadElementClass)head).appendChild((IHTMLDOMNode)scriptObject);
Я считаю, что самый простой способ ввести Javascript в HTML-документ WebBrowser Control из c# - это вызвать метод "execStrip" с кодом, который будет введен в качестве аргумента.
в этом примере код javascript вводится и выполняется в глобальной области:
var jsCode="alert('hello world from injected code');"; WebBrowser.Document.InvokeScript("execScript", new Object[] { jsCode, "JavaScript" });если вы хотите задержать выполнение, введите функции и вызовите их после:
var jsCode="function greet(msg){alert(msg);};"; WebBrowser.Document.InvokeScript("execScript", new Object[] { jsCode, "JavaScript" }); ............... WebBrowser.Document.InvokeScript("greet",new object[] {"hello world"});это допустимо для элементов управления Windows Forms и WPF WebBrowser.
этот решение не кросс-браузер, потому что "execScript" определяется только в IE и Chrome. Но вопрос заключается в Microsoft WebBrowser управления и IE является единственным поддерживаемым.
для допустимого кроссбраузерного метода для вставки кода javascript создайте объект функции с новым ключевым словом. В этом примере создается анонимная функция с введенным кодом и выполняется (javascript реализует замыкания, и функция имеет доступ к глобальному пространству без локальной переменной загрязнение.)
var jsCode="alert('hello world');"; (new Function(code))();конечно, вы можете отложить исполнение:
var jsCode="alert('hello world');"; var inserted=new Function(code); ................. inserted();надеюсь, что это помогает
как продолжение принято отвечать, это минимальное определение
IHTMLScriptElementинтерфейс который не требует включения дополнительных библиотек типа:[ComImport, ComVisible(true), Guid(@"3050f28b-98b5-11cf-bb82-00aa00bdce0b")] [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)] [TypeLibType(TypeLibTypeFlags.FDispatchable)] public interface IHTMLScriptElement { [DispId(1006)] string text { set; [return: MarshalAs(UnmanagedType.BStr)] get; } }таким образом, полный код внутри производного класса элемента управления WebBrowser будет выглядеть так:
protected override void OnDocumentCompleted( WebBrowserDocumentCompletedEventArgs e) { base.OnDocumentCompleted(e); // Disable text selection. var doc = Document; if (doc != null) { var heads = doc.GetElementsByTagName(@"head"); if (heads.Count > 0) { var scriptEl = doc.CreateElement(@"script"); if (scriptEl != null) { var element = (IHTMLScriptElement)scriptEl.DomElement; element.text = @"function disableSelection() { document.body.onselectstart=function(){ return false; }; document.body.ondragstart=function() { return false; }; }"; heads[0].AppendChild(scriptEl); doc.InvokeScript(@"disableSelection"); } } } }
я использовал это :D
HtmlElement script = this.WebNavegador.Document.CreateElement("SCRIPT"); script.SetAttribute("TEXT", "function GetNameFromBrowser() {" + "return 'My name is David';" + "}"); this.WebNavegador.Document.Body.AppendChild(script);затем вы можете выполнить и получить результат с:
string myNameIs = (string)this.WebNavegador.Document.InvokeScript("GetNameFromBrowser");Я надеюсь быть полезным
вы всегда можете использовать свойство "DocumentStream" или "DocumentText". Для работы с HTML-документами я рекомендую HTML Agility Pack.
вот это VB.Net пример, если вы пытаетесь получить значение переменной из страницы, загруженной в элемент управления WebBrowser.
Шаг 1) добавьте ссылку COM в свой проект в библиотеку объектов Microsoft HTML
Шаг 2) Далее, добавьте это VB.Net код для вашего Form1 для импорта библиотеки mshtml:
Импорт mshtmlШаг 3) Добавьте это VB.Net код над строкой" Public Class Form1":
Шаг 4) Добавьте элемент управления WebBrowser в свой проект
Шаг 5) Добавьте это VB.Net код для вашей функции Form1_Load:
Метода webbrowser1.ObjectForScripting = MeШаг 6) Добавьте это VB.Net sub, который будет вводить функцию "CallbackGetVar" в Javascript веб-страницы:
Public Sub InjectCallbackGetVar(ByRef wb As WebBrowser) Dim head As HtmlElement Dim script As HtmlElement Dim domElement As IHTMLScriptElement head = wb.Document.GetElementsByTagName("head")(0) script = wb.Document.CreateElement("script") domElement = script.DomElement domElement.type = "text/javascript" domElement.text = "function CallbackGetVar(myVar) { window.external.Callback_GetVar(eval(myVar)); }" head.AppendChild(script) End SubШаг 7) добавьте следующее VB.Net sub, который затем будет искать Javascript, когда вызывается:
Public Sub Callback_GetVar(ByVal vVar As String) Debug.Print(vVar) End SubШаг 8) Наконец, чтобы вызвать обратный вызов Javascript, добавьте это VB.Net код при нажатии кнопки, или где вам нравится:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click WebBrowser1.Document.InvokeScript("CallbackGetVar", New Object() {"NameOfVarToRetrieve"}) End SubШаг 9) Если вас удивляет, что это работает, вы можете прочитать о функции Javascript "eval", используемой в шаге 6, что и делает это возможным. Он примет строку и определит, существует ли переменная с этим именем, и если да, то возвращает значение этой переменной.
Что вы хотите сделать, это использовать страницу.RegisterStartupScript(ключ, сценарий) :
смотрите здесь для более подробной информации:http://msdn.microsoft.com/en-us/library/aa478975.aspx
в основном вы создаете свою строку javascript, передаете ее этому методу и даете ему уникальный идентификатор( в случае, если вы попытаетесь зарегистрировать его дважды на странице.)
EDIT: это то, что вы называете триггером счастливым. Не стесняйтесь его. :)
Если вам нужно ввести целый файл, то вы можете использовать это:
With Browser.Document' 'Dim Head As HtmlElement = .GetElementsByTagName("head")(0)' 'Dim Script As HtmlElement = .CreateElement("script")' 'Dim Streamer As New StreamReader(<Here goes path to file as String>)' 'Using Streamer' 'Script.SetAttribute("text", Streamer.ReadToEnd())' 'End Using' 'Head.AppendChild(Script)' '.InvokeScript(<Here goes a method name as String and without parentheses>)' 'End With'Не забудьте импортировать System.IO для того, чтобы использовать StreamReader. Я надеюсь, что это поможет
Я использую этот:
webBrowser.Document.InvokeScript("execScript", new object[] { "alert(123)", "JavaScript" })
Comments