1

I'm trying to get a page with AJAX, but when I get that page and it includes Javascript code - it doesn't execute it.

Why?

Simple code in my ajax page:

<script type="text/javascript">
alert("Hello");
</script>

...and it doesn't execute it. I'm trying to use Google Maps API and add markers with AJAX, so whenever I add one I execute a AJAX page that gets the new marker, stores it in a database and should add the marker "dynamically" to the map.

But since I can't execute a single javascript function this way, what do I do?

Is my functions that I've defined on the page beforehand protected or private?

** UPDATED WITH AJAX FUNCTION **

function ajaxExecute(id, link, query)
{
    if (query != null)
    {
        query = query.replace("amp;", "");
    }

    if (window.XMLHttpRequest)
    {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }
    else
    {
        // code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            if (id != null)
            {
                    document.getElementById(id).innerHTML=xmlhttp.responseText;
            }
        }
    }

    if (query == null)
    {
        xmlhttp.open("GET",link,true);
    }
    else
    {
        if (query.substr(0, 1) != "?")
        {
            xmlhttp.open("GET",link+"?"+query,true);
        }
        else
        {
            xmlhttp.open("GET",link+query,true);
        }
    }
    xmlhttp.send();
}

** Solution by Deukalion **

var content = xmlhttp.responseText;

if (id != null)
{

    document.getElementById(id).innerHTML=content;
    var script = content.match("<script[^>]*>[^<]*</script>");

    if (script != null)
    {
        script = script.toString().replace('<script type="text/javascript">', '');
        script = script.replace('</script>', '');
        eval(script);

    }
}

and on certain events, I had to within the script addevent listeners instead of just making a "select onchange='executeFunctionNotIncludedInAjaxFile();'" I had to addEventListener("change", functionName, false) for this. In the script that is being evaluated.

Pointy
  • 405,095
  • 59
  • 585
  • 614
Deukalion
  • 2,516
  • 9
  • 32
  • 50

4 Answers4

5

When you update your page by doing something like setting a container's innerHTML to some updated content, the browser simply will not run the scripts in it. You can locate the <script> tags, get their innerHTML (IE may prefer innerTEXT), and then eval() the scripts yourself (which is pretty much what jQuery does, though it finds the scripts with a regex before updating the DOM).

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • I was able to regex the scripts, so I can get only the scripts. Then I run eval at them, but it doesn't work with... say added DOM Elements that have scripts in them that reference main functions not loaded through AJAX. – Deukalion Jun 04 '12 at 23:22
  • What if the server returned straight javascript? That would make `eval` a lot easier to use. (but beware of [CSRF](http://incompleteness.me/blog/2007/01/01/csrf-attacks-or-how-to-avoid-exposing-your-gmail-contacts/). ) – Alexander Bird Jun 05 '12 at 00:29
  • Yes of course; if what you get back is pure JavaScript, then it's a different deal. And it is definitely important to understand the trust issues. – Pointy Jun 05 '12 at 03:41
3

Use this function:

function parseScript(_source) {
    var source = _source;
    var scripts = new Array();

    // Strip out tags
    while(source.indexOf("<script") > -1 || source.indexOf("</script") > -1) {
        var s = source.indexOf("<script");
        var s_e = source.indexOf(">", s);
        var e = source.indexOf("</script", s);
        var e_e = source.indexOf(">", e);

        // Add to scripts array
        scripts.push(source.substring(s_e+1, e));
        // Strip from source
        source = source.substring(0, s) + source.substring(e_e+1);
    }

    // Loop through every script collected and eval it
    for(var i=0; i<scripts.length; i++) {
        try {
            eval(scripts[i]);
        }
        catch(ex) {
            // do what you want here when a script fails
        }
    }

    // Return the cleaned source
    return source;
}

then do parseScript(xmlhttp.responseText); when you're replacing/adding content.

Jake
  • 1,469
  • 4
  • 19
  • 40
2

In case some other people stumble upon this old thread, there is one issue with the accepted answer by Deukalion, there is one issue that may have been overlooked: as written, the script only looks for the first script tag. If multiple script tags exist, all others are overlooked.

A few minor tweaks would resolve the issue. Change one line from:

    var script = content.match("<script[^>]*>[^<]*</script>");

To:

    var script = content.match(/<script[^>]*>[^<]*<\/script>/g);

And another from:

    script = script.toString().replace('<script type="text/javascript">', '');

To:

    script = script.join("").replace(/<script type="text\/javascript">/g, '');

Now it will gather all the <script> code and execute them in the order found on the page. Otherwise it was an excellent solution.

0

After the AJAX request, you can make an "on success" function which can take the returned html and do something with it. Then something will be executed.

If there was a code example, then I could provide a code solution to the situation. But using just standard xmlhttprequest, the following could be done:

xhr = new XMLHttpRequest();
xhr.open("GET","ajax_info.txt",true);
xhr.onreadystatechange=function()
{
if (xhr.readyState==4 && xhr.status==200)
  {
  document.getElementById("myDiv").innerHTML = xhr.responseText;
  }
}
xhr.send();
​
Alexander Bird
  • 38,679
  • 42
  • 124
  • 159
  • My method looks similiar, although I have a more dynamic ajax function. It works fine, except executing javascripts. I'll add the code to my post. – Deukalion Jun 04 '12 at 22:37
  • @Deukalion, no problem, and I like the flexibility of your solution you posted in your question. P.S. If my answer was what helped, please upvote and/or check as answered. Thanks! :) – Alexander Bird Jun 04 '12 at 22:56
  • No, it didn't. My php file included a simple "alert()" but it didn't execute it. And I can't reach functions staticly built when loading a page with Ajax. – Deukalion Jun 04 '12 at 23:07