Using eval for contents retrieved with XMLHttpRequest()

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • knocte

    Using eval for contents retrieved with XMLHttpRequest()

    Hello.

    I have always thought that the eval() function was very flexible and
    useful. If I use it, I can define functions at runtime!!

    However, I have found a case where eval() does not work properly. It
    works, for example, when invoking functions (alert('hello') ), but not
    for defining functions.

    The case occurs when retrieving the javascript code with
    XMLHttpRequest( ). It fails on Mozilla/Firefox and IE!

    I will quote the code:

    <script>
    function RequestDocument (sURL, bAsync) {
    var oXmlRequest;



    /* branch for native XMLHttpRequest object */
    if (window.XMLHttp Request) {
    oXmlRequest = new XMLHttpRequest( );
    oXmlRequest.ope n("GET", sURL, bAsync);
    oXmlRequest.sen d(null);
    }
    /* branch for IE/Windows ActiveX version */
    else if (window.ActiveX Object) {
    oXmlRequest = new ActiveXObject(" Microsoft.XMLHT TP");
    oXmlRequest.ope n("GET", sURL, bAsync);
    oXmlRequest.sen d();
    }

    return oXmlRequest;
    }

    function EvalScriptFile( oDocument){
    if (oDocument){

    /* only if status shows "loaded" */
    if (oDocument.read yState == 4) {

    /* only if "OK" */
    if (oDocument.stat us == 200) {
    eval(oDocument. responseText);
    }
    else if (oDocument.stat us == 404) {
    alert("File not found");
    }
    }
    }
    }

    function LoadScriptFile( sURL){
    var oScriptFileRequ est = RequestDocument (sURL,false);
    EvalScriptFile( oScriptFileRequ est);
    }











    //this works:
    eval("alert('he llo');function test(){ alert('test'); };");
    test();

    //but, if I put on a file (called mylib.js and located at the same
    //dir as this file on the web server), the following contents:
    // alert('hello2') ;
    // function test2(){ alert('test2'); };
    //
    LoadScriptFile( "mylib.js") ;
    test2();
    //the first alert is called (hello2)! but debugger says
    //that test2 is not defined!
    // what happens??
    </script>


    Do anybody know why?? Thanks in advance.

    Regards,

    Andrew

    --
  • Vladdy

    #2
    Re: Using eval for contents retrieved with XMLHttpRequest( )

    knocte wrote:[color=blue]
    > Hello.
    >
    > I have always thought that the eval() function was very flexible and
    > useful. If I use it, I can define functions at runtime!!
    >
    > However, I have found a case where eval() does not work properly. It
    > works, for example, when invoking functions (alert('hello') ), but not
    > for defining functions.
    >
    > The case occurs when retrieving the javascript code with
    > XMLHttpRequest( ). It fails on Mozilla/Firefox and IE!
    >
    > I will quote the code:
    >
    > <script>
    > function RequestDocument (sURL, bAsync) {
    > var oXmlRequest;
    >
    >
    >
    > /* branch for native XMLHttpRequest object */
    > if (window.XMLHttp Request) {
    > oXmlRequest = new XMLHttpRequest( );
    > oXmlRequest.ope n("GET", sURL, bAsync);
    > oXmlRequest.sen d(null);
    > }
    > /* branch for IE/Windows ActiveX version */
    > else if (window.ActiveX Object) {
    > oXmlRequest = new ActiveXObject(" Microsoft.XMLHT TP");
    > oXmlRequest.ope n("GET", sURL, bAsync);
    > oXmlRequest.sen d();
    > }
    >
    > return oXmlRequest;
    > }
    >
    > function EvalScriptFile( oDocument){
    > if (oDocument){
    >
    > /* only if status shows "loaded" */
    > if (oDocument.read yState == 4) {
    >
    > /* only if "OK" */
    > if (oDocument.stat us == 200) {
    > eval(oDocument. responseText);
    > }
    > else if (oDocument.stat us == 404) {
    > alert("File not found");
    > }
    > }
    > }
    > }
    >
    > function LoadScriptFile( sURL){
    > var oScriptFileRequ est = RequestDocument (sURL,false);
    > EvalScriptFile( oScriptFileRequ est);
    > }
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > //this works:
    > eval("alert('he llo');function test(){ alert('test'); };");
    > test();
    >
    > //but, if I put on a file (called mylib.js and located at the same
    > //dir as this file on the web server), the following contents:
    > // alert('hello2') ;
    > // function test2(){ alert('test2'); };
    > //
    > LoadScriptFile( "mylib.js") ;
    > test2();
    > //the first alert is called (hello2)! but debugger says
    > //that test2 is not defined!
    > // what happens??
    > </script>
    >
    >
    > Do anybody know why?? Thanks in advance.
    >
    > Regards,
    >
    > Andrew
    >[/color]
    Why would you use XMLHttpRequest to load a script? Following does an
    adequate job and does not require the use of eval

    loadScript(file Name)
    { var scr = document.create Element('script ');
    scr.type = 'text/javascript';
    scr.src = fileName;
    document.getEle mentsByTagName( 'head')[0].appendChild(sc r);
    }

    --
    Vladdy

    Comment

    • Don

      #3
      Re: Using eval for contents retrieved with XMLHttpRequest( )

      However, this sort of logical approach to injecting or inserting
      javascript dynamically does NOT work in the latest version of Safari.

      Comment

      • Randy Webb

        #4
        Re: Using eval for contents retrieved with XMLHttpRequest( )

        Don wrote:[color=blue]
        > However, this sort of logical approach to injecting or inserting
        > javascript dynamically does NOT work in the latest version of Safari.[/color]

        Does the XMLHTTPRequest object "work" in Safari?
        If not, then its a moot point.

        --
        Randy
        comp.lang.javas cript FAQ - http://jibbering.com/faq & newsgroup weekly

        Comment

        • Don

          #5
          Re: Using eval for contents retrieved with XMLHttpRequest( )

          Yes (most of the time).

          My errors with Safari have nothing to do with javascript insertion but
          getting anything (e.g. HTML) from ASP code using ajax. I keep getting
          errors, even after req.readyState == 4 where the req.status is
          undefined, the statusText is undefined, and the responseText is null.
          My code all works fine with Firefox and Netscape (and IE using the
          ActiveX object). The only way I can make the errors go away is by
          making the ajax calls synchronous rather than asynchronous, so I have
          to check for a Safari browser and set the synch flag appropriately.

          As for the dynamic javascript problem, Apple admits (a posting in one
          of the Apple groups) that it is different from other browsers in this
          way (they saw the js insertion functionality as a security issue) but
          still want to do what other browsers are capable of doing.

          Comment

          • Lasse Reichstein Nielsen

            #6
            Re: Using eval for contents retrieved with XMLHttpRequest( )

            knocte <knocte@NO-SPAM-PLEASE-gmail.com> writes:
            [color=blue]
            > I have always thought that the eval() function was very flexible and
            > useful.[/color]

            I feel the same way about flamethrowers :)
            [color=blue]
            > If I use it, I can define functions at runtime!![/color]

            What can you do with "eval" that you can't do with one or more
            function expressions?

            Working with syntax at runtime is ... volatile. Just like
            flamethrowers :)
            [color=blue]
            > However, I have found a case where eval() does not work properly.[/color]

            Not according to specification or not as you would want it to work?
            [color=blue]
            > It works, for example, when invoking functions (alert('hello') ), but
            > not for defining functions.[/color]

            .... but you said above that ... ? :P
            [color=blue]
            > The case occurs when retrieving the javascript code with
            > XMLHttpRequest( ). It fails on Mozilla/Firefox and IE![/color]
            [color=blue]
            > I will quote the code:[/color]

            Actual code and platform where it fails, as well as a description of
            the error later ... a good error report :) Keep it up!

            Have you tried any other browser?
            [color=blue]
            > <script>[/color]

            Use valid HTML. That way you can be sure that it's not the HTML that
            causes your problems. In this case:
            <script type="text/javascript">
            [color=blue]
            > function RequestDocument (sURL, bAsync) {
            > var oXmlRequest;
            >
            > /* branch for native XMLHttpRequest object */[/color]
            ....[color=blue]
            > else if (window.ActiveX Object) {
            > oXmlRequest = new ActiveXObject(" Microsoft.XMLHT TP");
            > oXmlRequest.ope n("GET", sURL, bAsync);
            > oXmlRequest.sen d();
            > }[/color]

            Why not set an onreadystatecha nge handler to inform you when the
            request is done (when asynchroneous)?

            Anyway...
            [color=blue]
            > function LoadScriptFile( sURL){
            > var oScriptFileRequ est = RequestDocument (sURL,false);
            > EvalScriptFile( oScriptFileRequ est);
            > }[/color]
            .....[color=blue]
            > //this works:
            > eval("alert('he llo');function test(){ alert('test'); };");
            > test();[/color]

            But does this work?
            ---
            function LoadScriptLiter al() {
            eval("alert('he llo');function test(){ alert('test'); };");
            }
            EvalScriptLiter al();
            test();
            ---

            It doesn't work, because the content is evaluated in the same scope as
            the call to eval. That means that the declaration of test() happens
            inside the function LoadScriptLiter al, and can't be seen outside of
            it.

            You have the same problem, because you call "eval" inside
            LoadScriptFile.


            One soultion would be to let the script declare its variables as
            global variables:

            var global = (function(){ret urn this;})();
            global.test2 = function() { alert("test2"); }

            Not as pretty, but guaranteed to work.

            I can't find a better way of doing it right now, but I'll keep
            pondering :)

            Good luck!
            /L
            --
            Lasse Reichstein Nielsen - lrn@hotpop.com
            DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
            'Faith without judgement merely degrades the spirit divine.'

            Comment

            • knocte

              #7
              Re: Using eval for contents retrieved with XMLHttpRequest( )

              Hello. Thanks for your answer!

              Lasse Reichstein Nielsen escribió:[color=blue]
              >[color=green]
              >>I have always thought that the eval() function was very flexible and
              >>useful.[/color]
              >
              > I feel the same way about flamethrowers :)[/color]

              Are you saying that I wanted to throw a flame?
              [color=blue][color=green]
              >>If I use it, I can define functions at runtime!![/color]
              >
              > What can you do with "eval" that you can't do with one or more
              > function expressions?[/color]

              I can run code that comes from an external source, for example.
              Hey, I know the disadvantages of eval(), I was just commenting its
              advantages.
              [color=blue]
              > Working with syntax at runtime is ... volatile. Just like
              > flamethrowers :)[/color]

              I don't understand what you mean.

              [color=blue][color=green]
              >>However, I have found a case where eval() does not work properly.[/color]
              >
              > Not according to specification or not as you would want it to work?[/color]

              Well, I actually didn't know.

              [color=blue][color=green]
              >>It works, for example, when invoking functions (alert('hello') ), but
              >>not for defining functions.[/color]
              >
              > ... but you said above that ... ? :P[/color]


              Excuse me? :?
              [color=blue][color=green]
              >>The case occurs when retrieving the javascript code with
              >>XMLHttpReques t(). It fails on Mozilla/Firefox and IE![/color]
              >[color=green]
              >>I will quote the code:[/color]
              >
              > Actual code and platform where it fails, as well as a description of
              > the error later ... a good error report :) Keep it up![/color]

              Well, if I say it fails on Mozilla/Firefox, I think the error is
              platform-independent...
              [color=blue]
              > Have you tried any other browser?[/color]

              No. I usually work with Mozilla or Firefox (because they respect
              standards) and I do some tests later with IE (for compatibility).
              [color=blue][color=green]
              >><script>[/color]
              >
              > Use valid HTML. That way you can be sure that it's not the HTML that
              > causes your problems. In this case:
              > <script type="text/javascript">[/color]

              Well, thanks for your advice but I think here it is irrevelant; above
              all, because I have used this "short" way so as not to paste unnecessary
              things to the list. It's just an example.
              [color=blue][color=green]
              >>function RequestDocument (sURL, bAsync) {
              >> var oXmlRequest;
              >>
              >> /* branch for native XMLHttpRequest object */[/color]
              > ...[color=green]
              >> else if (window.ActiveX Object) {
              >> oXmlRequest = new ActiveXObject(" Microsoft.XMLHT TP");
              >> oXmlRequest.ope n("GET", sURL, bAsync);
              >> oXmlRequest.sen d();
              >> }[/color]
              >
              > Why not set an onreadystatecha nge handler to inform you when the
              > request is done (when asynchroneous)?[/color]

              Because I am using synchronous mode in this case. I don't need it.
              [color=blue]
              > Anyway...
              >[color=green]
              >>function LoadScriptFile( sURL){
              >> var oScriptFileRequ est = RequestDocument (sURL,false);
              >> EvalScriptFile( oScriptFileRequ est);
              >>}[/color]
              > ....[color=green]
              >>//this works:
              >>eval("alert(' hello');functio n test(){ alert('test'); };");
              >>test();[/color]
              >
              > But does this work?
              > ---
              > function LoadScriptLiter al() {
              > eval("alert('he llo');function test(){ alert('test'); };");
              > }
              > EvalScriptLiter al();
              > test();
              > ---
              >
              > It doesn't work, because the content is evaluated in the same scope as
              > the call to eval. That means that the declaration of test() happens
              > inside the function LoadScriptLiter al, and can't be seen outside of
              > it.
              >
              > You have the same problem, because you call "eval" inside
              > LoadScriptFile.
              >[/color]

              Yes, you got it. I doesn't have many experience with
              javascript/ecmascript and I thought that, as well as for this language
              the scope inside an "if" is the same as the one outside, it would happen
              the same with functions, but I was wrong.
              [color=blue]
              > One soultion would be to let the script declare its variables as
              > global variables:
              >
              > var global = (function(){ret urn this;})();
              > global.test2 = function() { alert("test2"); }
              >
              > Not as pretty, but guaranteed to work.
              >
              > I can't find a better way of doing it right now, but I'll keep
              > pondering :)
              >
              > Good luck!
              > /L[/color]

              Hey, I find this way very useful to allow external functions access to
              the global scope! Thanks very much for your comments.

              Andrew

              --

              Comment

              • knocte

                #8
                Re: Using eval for contents retrieved with XMLHttpRequest( )

                Vladdy escribió:[color=blue]
                > Why would you use XMLHttpRequest to load a script? Following does an
                > adequate job and does not require the use of eval
                >
                > loadScript(file Name)
                > { var scr = document.create Element('script ');
                > scr.type = 'text/javascript';
                > scr.src = fileName;
                > document.getEle mentsByTagName( 'head')[0].appendChild(sc r);
                > }
                >[/color]

                Thanks for your suggestion, but I prefer to use XMLHttpRequest this
                time, for many reasons:

                - I can control better when the javascript is evaluated, because I don't
                delegate this task to the browser.
                - I can do it synchronously, so as to wait until the file called is
                loaded before loading more javascript code.
                - I will be able to use this method even with bad-formed HTML documents
                (for example, those without a head tag).

                Regards,

                Andrew

                --

                Comment

                • VK

                  #9
                  Re: Using eval for contents retrieved with XMLHttpRequest( )

                  > The case occurs when retrieving the javascript code with[color=blue]
                  > XMLHttpRequest( ). It fails on Mozilla/Firefox and IE![/color]

                  Actually XMLHTTP doesn't stay from "get XML or HTTP or whatever you'll
                  get in your head". It stays from "get XML data for HTML environment
                  (browser)". But I'm affraid that all hell broke loose already. Mr.
                  Knocte is getting his JavaScript this way, someone already tried to get
                  binary data stream. So soon I guess we'll see XMLHTTP used to download
                  music, pictures and "Star Wars Episode 3". So shall be it...

                  Comment

                  • Razzbar

                    #10
                    Re: Using eval for contents retrieved with XMLHttpRequest( )

                    So shall also be many users scratching their heads as their browsers
                    hang useless, because some cowboy figured that if you put your JS
                    functions on the server and use a synchronous call, you are guaranteed
                    they will come a'running ever time, and execute when you want them to,
                    not before.

                    Comment

                    • knocte

                      #11
                      Re: Using eval for contents retrieved with XMLHttpRequest( )

                      Razzbar escribió:[color=blue]
                      > So shall also be many users scratching their heads as their browsers
                      > hang useless, because some cowboy figured that if you put your JS
                      > functions on the server and use a synchronous call, you are guaranteed
                      > they will come a'running ever time, and execute when you want them to,
                      > not before.
                      >[/color]

                      If JS don't work, my sites fallback to the fact that they don't support
                      client-side scripting, then many browsers will be supported only because
                      of this.

                      Regards,

                      knocte

                      --

                      Comment

                      • knocte

                        #12
                        Re: Using eval for contents retrieved with XMLHttpRequest( )

                        VK escribió:[color=blue][color=green]
                        >>The case occurs when retrieving the javascript code with
                        >>XMLHttpReques t(). It fails on Mozilla/Firefox and IE![/color]
                        >
                        > Actually XMLHTTP doesn't stay from "get XML or HTTP or whatever you'll
                        > get in your head". It stays from "get XML data for HTML environment
                        > (browser)". But I'm affraid that all hell broke loose already. Mr.
                        > Knocte is getting his JavaScript this way, someone already tried to get
                        > binary data stream. So soon I guess we'll see XMLHTTP used to download
                        > music, pictures and "Star Wars Episode 3". So shall be it...
                        >[/color]

                        Actually, I think the feature should be just called "HttpReques t",
                        because nothing prevents me for getting anything I want with the Http
                        protocol using this.

                        Regards,

                        knocte

                        P.S.: Perhaps you should suggest to the responsible for DOM specs to
                        delete the accessibility to the ".responseT ext" attribute. That way
                        you'll be able to dictate how the technologies must be used.

                        --

                        Comment

                        • VK

                          #13
                          Re: Using eval for contents retrieved with XMLHttpRequest( )

                          > Actually, I think the feature should be just called "HttpReques t",[color=blue]
                          > because nothing prevents me for getting anything I want with
                          > the Http protocol using this.[/color]

                          "Who can stop Hafiz from likening a ladybug to the Padishah"
                          An old Persian proverbe ;-)

                          <http://groups-beta.google.com/group/comp.lang.javas cript/browse_frm/thread/f6ce0a5e95d8bf3 0/ba5264709e33894 e?q=group:comp. lang.javascript +author:VK&rnum =19&hl=en#ba526 4709e33894e>

                          Comment

                          Working...