WebBrowser नियंत्रण में जावास्क्रिप्ट कैसे इंजेक्ट करें?


81

मैंने यह कोशिश की है:

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.InnerText दोनों त्रुटियां देते हैं:

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:\jsight\installs\SForceApp\SForceApp\Form1.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)

क्या किसी स्क्रिप्ट को डोम में इंजेक्ट करने का एक आसान तरीका है?

जवाबों:


101

किसी कारण के लिए रिचर्ड का समाधान मेरे अंत पर काम नहीं करता था (सम्मिलित विज्ञापन एक अपवाद के साथ विफल हुआ)। हालांकि यह काम करने लगता है:

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इंटरफ़ेस को अपनी परियोजना में कैसे लाया जाए ।


1
कूल, मुझे लगता है कि IHTMLScriptElement उपयोग किसी भी मामले में कोड के इरादे को अधिक स्पष्ट बनाता है। मुझे आश्चर्य है कि आपको अपवाद क्यों मिला, लेकिन कभी-कभी COM इंटरॉप के साथ c'est la vie होता है।
ZeroBugBounce 20

स्थानीय js फ़ाइल के संदर्भ को जोड़ने के बारे में क्या? कृपया देखें stackoverflow.com/questions/4029602/…
IAmAN00B

इसमें मेरी मदद करो। आपने इसे कैसे किया। मैं अपने सी ++ ऐप के माध्यम से वास्तविक समय में जेएस को अपने पेज में इंजेक्ट करना चाहता हूं। मुझे इसे किस प्रकार करना चाहिए।
जॉनयडेप

यह jquery फ़ाइल को भी इंजेक्ट करने के लिए लागू है?
गमरु

51
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 / विंडोज फॉर्म ऐप में परीक्षण किया गया)

संपादित करें: फ़ंक्शन सेट में फिक्स्ड केस मुद्दा।


12
मैंने इस समाधान की सराहना की क्योंकि यह (यद्यपि उपयोगी!) IHTMLSCriptElement विधानसभा पर भरोसा नहीं करता है।
मीका स्मिथ

6
@jsight यह स्वीकृत उत्तर होना चाहिए। यह वर्तमान उत्तर के समान है, लेकिन सरल और IHTMLSCriptElementनिर्भरता के बिना ।
ब्लूराजा - डैनी पफ्लुगुएफ्ट

32

यहाँ सबसे आसान तरीका है जो मुझे इस पर काम करने के बाद मिला है:

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 });

वैश्विक जावास्क्रिप्ट फ़ंक्शन क्या eval(str)करता है और जो कुछ भी स्ट्रिंग में लिखा गया है उसे निष्पादित करता है। चेक w3schools यहाँ रेफरी


22

इसके अलावा, .NET 4 में यदि आप डायनामिक कीवर्ड का उपयोग करते हैं तो यह और भी आसान है:

dynamic document = this.browser.Document;
dynamic head = document.GetElementsByTagName("head")[0];
dynamic scriptEl = document.CreateElement("script");
scriptEl.text = ...;
head.AppendChild(scriptEl);

2
उसके लिए किसी को गतिशील की आवश्यकता क्यों होगी? यदि आप कुछ टाइपिंग को बचाने की कोशिश कर रहे हैं, तो हमारे पास C # 3.0 के बाद से टाइप इनफैक्शन है, इसलिए var स्वीकार्य होगा। DLR शुरू करने की कोई आवश्यकता नहीं है।
अलिंबडा

23
यह मूल रूप से गतिशील कीवर्ड का बिंदु है: COM इंटरॉप। आपके पास वास्तव में टाइप इंफ़ेक्शन नहीं है, आपके पास दस्तावेज़ हैं। क्योंकि IHTMLElement2 उदाहरण के लिए IHtmlElement से असाइन करने योग्य नहीं है, और रनटाइम में आपके पास सिर्फ COM प्रॉक्सी ऑब्जेक्ट है। आपको बस यह जानना होगा कि कौन सा इंटरफेस किस में डालना है। डायनामिक कीवर्ड आपको उस क्रॉफ्ट पर बहुत अधिक कटौती करने में मदद करता है। आपको पता है कि यह विधि मौजूद है कि इसे कुछ इंटरफ़ेस में क्यों डाला जाए? यह वास्तव में 'DLR' को लागू नहीं करता है यह सिर्फ कोड बनाता है जो जानता है कि COM ऑब्जेक्ट (इस मामले में) पर विधि कैसे लागू करें।
justin.m.chase

1
@ justin.m.chase आपने मेरी जान बचाई।
खिजर इकबाल

17

यदि आप वास्तव में चाहते हैं कि जावास्क्रिप्ट को चलाया जाए, तो यह सबसे आसान होगा (VB .Net)।

MyWebBrowser.Navigate("javascript:function foo(){alert('hello');}foo();")

मुझे लगता है कि यह इसे "इंजेक्ट" नहीं करेगा, लेकिन यह आपके कार्य को चलाएगा, यदि आप इसके बाद हैं। (यदि आप समस्या को खत्म कर चुके हैं, तो बस।) और यदि आप यह जान सकते हैं कि जावास्क्रिप्ट में कैसे इंजेक्ट किया जाए, तो इसे फंक्शन "फू" के शरीर में डालें और जावास्क्रिप्ट को आपके लिए इंजेक्शन दें।


10

HTML दस्तावेज़ के लिए प्रबंधित आवरण पूरी तरह से आपके द्वारा आवश्यक कार्यक्षमता को लागू नहीं करता है, इसलिए आपको जो कुछ भी करना है उसे पूरा करने के लिए MSHTML API में डुबकी लगाने की आवश्यकता है:

1) MSHTML के लिए एक संदर्भ जोड़ें, जिसे COM संदर्भों के तहत "Microsoft HTML ऑब्जेक्ट लाइब्रेरी" कहा जाएगा ।

2) 'mshtml का उपयोग कर;' आपके नाम स्थान पर।

3) अपने स्क्रिप्ट तत्व के IHTMLElement का संदर्भ लें:

IHTMLElement iScriptEl = (IHTMLElement)scriptEl.DomElement;

4) "आफ्टरबीगिन" के पहले पैरामीटर मान के साथ, सम्मिलित करें। सभी संभावित मूल्य यहां सूचीबद्ध हैं :

iScriptEl.insertAdjacentText("afterBegin", "function sayHello() { alert('hello') }");

5) अब आप scriptEl.InnerText प्रॉपर्टी में कोड देख पाएंगे।

हीथ, रिचर्ड


1
अच्छा ... यह एक साथ पूरी तरह से काम करता है सुझावों के साथ प्रदान करता है। काश मैं इस पर दो स्वीकृत समाधान सेट कर सकता। :)
jsight

8

स्वीकृत उत्तर के अनुवर्ती के रूप में , यह 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");
            }
        }
    }
}

8

मेरा मानना ​​है कि WebBrowser Control HTML डॉक्यूमेंट में जावास्क्रिप्ट को इंजेक्ट करने के लिए सबसे सरल तरीका है c # से कोड के साथ "एक्जीक्यूट" विधि को तर्क के रूप में इंजेक्ट करना है।

इस उदाहरण में जावास्क्रिप्ट कोड को वैश्विक दायरे में इंजेक्ट और निष्पादित किया जाता है:

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"});

यह विंडोज फॉर्म और WPF WebBrowser नियंत्रण के लिए मान्य है।

यह समाधान ब्राउज़र पार नहीं है क्योंकि "निष्पादक" केवल IE और क्रोम में परिभाषित किया गया है। लेकिन सवाल Microsoft WebBrowser नियंत्रण के बारे में है और IE केवल एक समर्थित है।

जावास्क्रिप्ट कोड को इंजेक्ट करने के लिए एक वैध क्रॉस ब्राउज़र विधि के लिए, नए कीवर्ड के साथ एक फंक्शन ऑब्जेक्ट बनाएं। यह उदाहरण इंजेक्ट कोड के साथ एक अनाम फ़ंक्शन बनाता है और इसे निष्पादित करता है (जावास्क्रिप्ट के कार्यान्वयन बंद हो जाते हैं और फ़ंक्शन में स्थानीय चर प्रदूषण के बिना वैश्विक स्थान तक पहुंच होती है)।

var jsCode="alert('hello world');";
(new Function(code))();

बेशक, आप निष्पादन में देरी कर सकते हैं:

var jsCode="alert('hello world');";
var inserted=new Function(code);
.................
inserted();

आशा है कि इससे सहायता मिलेगी


7

यह 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);

2
जैसा कि यह एक सामुदायिक संसाधन है, उसका जवाब अभी भी दूसरों के लिए उपयोगी है (जैसे खुद)। Mshtml समकक्ष के लिए +1, ने मुझे एक प्रश्न बचाया।
Kyeotic

1
जो कोई भी इसे पाता है, उसके लिए अंतिम पंक्ति से 'क्लास' हटा दें, ((HTMLHeadElement)head).appendChild((IHTMLDOMNode)scriptObject);आपको पढ़ना चाहिए अन्यथा आपको त्रुटियां मिलेंगी।
कायोटिक

1
वैसे भी क्या इस उत्तर को प्रशंसा द्वारा बढ़ावा मिल सकता है? इससे ऊपर वाले सभी वास्तविकता में गलत हैं। यह एक देर से हास्य था, लेकिन वास्तव में सबसे सही उत्तर है।
justin.m.chase

2

मैंने इसका इस्तेमाल किया: डी

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");

मुझे मददगार होने की उम्मीद है


2

यदि आप किसी WebBrowser नियंत्रण में लोड किए गए पृष्ठ के भीतर से किसी चर का मान प्राप्त करने का प्रयास कर रहे हैं, तो यहां VB.Net उदाहरण है।

चरण 1) Microsoft HTML ऑब्जेक्ट लाइब्रेरी में अपनी परियोजना में एक COM संदर्भ जोड़ें

चरण 2) अगला, mshtml लाइब्रेरी को आयात करने के लिए इस VB.Net कोड को अपने फॉर्म 1 में जोड़ें:
Imports mshtml

चरण 3) अपने "पब्लिक क्लास फॉर्म 1" लाइन के ऊपर यह VB.Net कोड जोड़ें:
<System.Runtime.InteropServices.ComVoubleAttribute (ट्रू)>

चरण 4) अपने प्रोजेक्ट में एक WebBrowser नियंत्रण जोड़ें

चरण 5) इस VB.Net कोड को अपने Form1_Load फ़ंक्शन में जोड़ें:
WebBrowser1.ObjectForing = मैं

चरण 6) इस VB.Net उप को जोड़ें जो वेब पेज के जावास्क्रिप्ट में एक फ़ंक्शन "CallbackGetVar" को इंजेक्ट करेगा।

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 उप को जोड़ें जिसे जावास्क्रिप्ट तब आमंत्रित किया जाएगा जब वह देखेगा:

Public Sub Callback_GetVar(ByVal vVar As String)
    Debug.Print(vVar)
End Sub

चरण 8) अंत में, जावास्क्रिप्ट कॉलबैक को आमंत्रित करने के लिए, एक बटन दबाए जाने पर, या जहां कहीं भी हो, इस 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) यदि यह आपको आश्चर्यचकित करता है कि यह काम करता है, तो आप चरण 6 में उपयोग किए जाने वाले जावास्क्रिप्ट "eval" फ़ंक्शन पर पढ़ना चाह सकते हैं, जो कि यह संभव बनाता है। यह एक स्ट्रिंग लेगा और निर्धारित करेगा कि क्या एक चर उस नाम के साथ मौजूद है और यदि हां, तो उस चर का मान लौटाता है।


1

आप हमेशा "डॉक्यूमेंटस्ट्रीम" या "डॉक्यूमेंट टेक्स्ट" संपत्ति का उपयोग कर सकते हैं। HTML दस्तावेजों के साथ काम करने के लिए मैं एक HTML चपलता पैक की सलाह देता हूं ।


अच्छा टिप ... मुझे यकीन है कि कुछ बिंदु पर काम आ जाएगा।
jsight

1

मैं इसका उपयोग करता हूं:

webBrowser.Document.InvokeScript("execScript", new object[] { "alert(123)", "JavaScript" })

0

आप जो करना चाहते हैं वह Page.RegisterStartupScript (कुंजी, स्क्रिप्ट) का उपयोग करना है:

अधिक जानकारी के लिए यहां देखें: http://msdn.microsoft.com/en-us/library/aa478975.aspx

आप मूल रूप से अपनी जावास्क्रिप्ट स्ट्रिंग का निर्माण करते हैं, इसे उस तरीके से पास करते हैं और इसे एक अद्वितीय आईडी देते हैं (यदि आप किसी पृष्ठ पर इसे दो बार पंजीकृत करने का प्रयास करते हैं।)

संपादित करें: यह वह है जिसे आप ट्रिगर कहते हैं खुश। इसे नीचे करने के लिए स्वतंत्र महसूस करें। :)


4
ASP.Net को एक winforms ऐप में WebBrowser नियंत्रण को स्क्रिप्ट करने के साथ बहुत कुछ नहीं करना है।
jsight

मैंने शायद उसी तरह से पढ़ा-लिखा होगा और उसी गलत जवाब को दिया होगा
Grank 30'08

0

यदि आपको पूरी फ़ाइल इंजेक्ट करने की आवश्यकता है तो आप इसका उपयोग कर सकते हैं:

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। आशा है कि ये आपकी मदद करेगा।


मुझे पता है कि यह एक साल पहले 3 दिन छोटा था, लेकिन क्या आप इसका उपयोग किसी input type="file"अनुभाग में फ़ाइल डालने में कर पाएंगे ?
क्रिस हॉब्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.