WebBrowser 注入 JS 具体 Delphi 代码如下:
procedure TfrmMain.LoatExternalJS; var i:integer; o:OleVariant; begin o := WebBrowser1.OleObject.document.createElement('script'); o.type := 'text/javascript'; o.text := 'alert("Hello, JS 注入成功!");'; // 注意这里 WebBrowser1.OleObject.document.getElementsByTagName('head').item(0).appendChild(o); end; procedure TfrmMain.WebBrowser1DocumentComplete(ASender: TObject; const pDisp: IDispatch; const URL: OleVariant); begin if WebBrowser1.LocationURL = URL then begin LoatExternalJS(); // 在页面加载完成的时候,调用 JS 注入 end; Memo1.Lines.Add(WebBrowser1.LocationURL); end;
WebBrowser 注入 JS 具体 Delphi 最终效果如下:
Delphi WebBrowser JS 注入
刚才的 WebBrowser 注入 JS 是直接 text
代码片段,如果希望直接引入的是 JS 文件,则具体 Delphi 代码改成 o.src
即可:
procedure TfrmMain.LoatExternalJS; var i:integer; o:OleVariant; begin o := WebBrowser1.OleObject.document.createElement('script'); o.type := 'text/javascript'; o.src := 'https://commandnotfound.cn/plugin.js'; // 注意这里 JS 的 src WebBrowser1.OleObject.document.getElementsByTagName('head').item(0).appendChild(o); end; ...
其他 StackOverflow 上的一个完整例子,需要用到 IHtmlScriptElement
:
unit u_frm_SO27091639; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, OleCtrls, SHDocVw, MsHtml, ActiveX; type TForm1 = class(TForm) WebBrowser1: TWebBrowser; Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure LoadDocFromString(Webbrowser : TWebbrowser); var Strm : TStringStream; Adapter : TStreamAdapter; begin WebBrowser.Navigate('about:blank'); // warning - don't use this trick in production code, use the `OnDocumentComplete` event while WebBrowser.ReadyState <> READYSTATE_INTERACTIVE do Application.ProcessMessages; // end of warning Strm := TStringStream.Create; try Strm.WriteString('<html><body>Something<br></body></html>'); Strm.Seek(0, 0); Adapter := TStreamAdapter.Create(Strm); (WebBrowser.Document as IPersistStreamInit).Load(Adapter) ; finally Strm.Free; end; end; procedure TForm1.Button1Click(Sender: TObject); var Doc2 : IHtmlDocument2; Script : IHtmlDOMNode; HTMLWindow: IHTMLWindow2; begin Doc2 := Webbrowser1.Document as IHtmlDocument2; if Assigned(Doc2.body) then begin Script := Doc2.createElement('script') as IHTMLDOMNode; (Script as IHTMLScriptElement).text := 'function helloWorld() { alert("hello world!") }'; (Doc2.body as IHtmlDomNode).appendChild(Script); HTMLWindow := Doc2.parentWindow; if Assigned(HTMLWindow) then HTMLWindow.execScript('helloWorld()', 'JavaScript') end; end; procedure TForm1.FormCreate(Sender: TObject); begin LoadDocFromString(Webbrowser1); end; end.
exjsUrl = "https://commandnotfound.cn/plugin.js"; private void LoadExternalJs() { var head = this.browser.Document.GetElementsByTagName("head"); if (head == null || browser.Document.GetElementById("ex_js") != null) return; var script = browser.Document.CreateElement("script"); script.SetAttribute("type", "text/javascript"); script.SetAttribute("id", "ex_js"); script.SetAttribute("src", exjsUrl); head[0].AppendChild(script); } private void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { if (e.Url == browser.Url) { LoadExternalJs(); ... } }
C# 追加 script
元素,这个方式,可以传参及取得返回值。
var script = browser.Document.CreateElement("script"); script.SetAttribute("type", "text/javascript"); script.SetAttribute("text", "function _func() {" + string.Format(jsCode, "method 1") + "}"); browser.Document.Body.AppendChild(script); browser.Document.InvokeScript("_func"); }
C# DomDocument ,这种方式,必须在程序中引用 MSHTML 对象(不能传参,且没有返回值):
var doc = this.browser.Document.DomDocument as IHTMLDocument2; var win = doc.parentWindow as IHTMLWindow2; jsCode = string.Format(jsCode, "method 2"); win.execScript(jsCode, "javascript");
C# 还有一个简单方式,直接调用:
browser.Document.InvokeScript("execScript", new Object[] { string.Format(jsCode, "method 3"), "javascript" });