Using Ajax to return JavaScript scripts in HTML fragments _javascript tips

Source: Internet
Author: User
Tags script tag javascript eval
This is a common problem in AJAX development, and if you're not constantly developing javascript frameworks, you'll probably find out. This article analyzes two solutions, one of which is to explain the implementation of the jquery framework.

I. Description of the problem
Here's a simple example to illustrate the problem. In the following example, suppose the variable responsetext is an AJAX-loaded HTML fragment that contains a script that pops up a message and inserts a DIV with an ID of ajaxdata with the innerHTML method, and you might expect to see the pop-up message box, and you'll find no This is the problem.
Copy Code code as follows:

<div id= "Ajaxdata" ></div>
<script type= "Text/javascript" >
var responsetext = ' <p> This is a paragraph </p><script>alert ("This is Ajax loaded back script fragment") </script> ';
document.getElementById (' Ajaxdata '). InnerHTML = ResponseText;
</script>

Ii. two ways of solving the problem
1. Execute the script using the JavaScript eval method.

The idea of this method is to extract the script from the Xmlhttp.responsetext, regardless of how many script blocks are included in the Ajax-loaded HTML, we call the Eval method to execute it on the found script block. The following provides a encapsulated function:
Copy Code code as follows:

function Executescript (HTML)
{
var reg =/<script[^>]*> ([^\x00]+) $/i;
Split the entire segment of HTML by <\/script>
var htmlblock = html.split ("<\/script>");
for (var i in Htmlblock)
{
The Var blocks;//matches the array of contents of the regular expression, blocks[1] is really a piece of script, because the front reg definition we used parentheses to capture the grouping
if (blocks = Htmlblock[i].match (reg))
{
Clears possible annotation tokens,--> can ignore processing at the end of comments, and Eval works as normal
var code = blocks[1].replace (/<!--/, "");
Try
{
Eval (code)//Execute script
}
catch (E)
{
}
}
}
}

The use of this method is as follows, the HTML is added to the DOM with the innerHTML method, followed by the call to the Executescript method to execute the script block:
Copy Code code as follows:

document.getElementById ("Div1"). InnerHTML = Xmlhttp.responsetext;
Executescript (Xmlhttp.responsetext);

Obviously this method is still flawed if Xmlhttp.responsetext contains an external script call like this:
The <script type= "Text/javascript" src= "/js/common.js" ></script>,executescript method can no longer further execute this externally loaded script.

2, learning and using the implementation of the jquery framework

jquery loads HTML for Ajax, which ultimately translates the entire xmlhttp.responsetext data into DOM when executing the HTML (value) method, and then uses DOM-related how-to methods to find the script inside, and then inserts the script into the head. The specific principle is also difficult to say, first give the simplest example, and then analyze the general idea. First look at the example:
Copy Code code as follows:

$.get (' ajax.aspx ', function (data)
{
$ (' #div1 '). HTML (data);
});

Now assume that the above ajax.aspx page returns an HTML fragment and contains one or more script blocks, even external script references. The DIV1 is the ID of a DIV tag for the AJAX Request Initiation page, and the result of the whole code implementation is to load the HTML in the ajax.aspx into a div tag with an ID of DIV1.

In an anonymous callback function, data can be found by typeof (data) or the original string. That is, equivalent to Xmlhttp.responsetext, through code Execution trace discovery, the execution of the Ajax loading script fragment is not in jquery's Ajax module code, but in the HTML (value) method, That is, when an HTML string containing a script block is inserted into the DOM, it is responsible for extracting the script for invocation processing. The HTML (value) method actually calls the append (value) method ..., and the entire process probably calls the following methods, and the arrows represent the order in which they are invoked:

HTML-> append-> dommanip-> clean-> evalscript-> globaleval

The clean method is particularly critical, and this method is also an important method for jquery, which involves fixing HTML errors (tags do not end, table structure adjustment, etc.) processing scripts. And the extraction of the script is also done here. Look at the relevant source code (JQUERY1.3.2):
Copy Code code as follows:

if (fragment)
{
for (var i = 0; ret[i]; i++)
{
if (Jquery.nodename (Ret[i], "script") && (!ret[i].type | | ret[i].type.tolowercase () = = "Text/javascript"))
{
Scripts.push (Ret[i].parentnode ret[i].parentnode.removechild (Ret[i]): Ret[i]);
}
Else
{
if (Ret[i].nodetype = = 1)
Ret.splice.apply (ret, [i + 1, 0].concat (Jquery.makearray (Ret[i].getelementsbytagname ("script")));
Fragment.appendchild (Ret[i]);
}
}
return scripts;
}

In addition, in the Evalscript method we also found the following code, here is the "same" step loading like <script type= "Text/javascript" src= "/js/common.js" ></script> Such an external script solves a flaw in the executescript approach:
Copy Code code as follows:

if (ELEM.SRC)
Jquery.ajax (
{
URL:ELEM.SRC,
Async:false,
DataType: "Script"
});

It also found the following code, which deletes the script in Xmlhttp.responsetext, because in this method, jquery is ready to put the extracted script into the head area, so delete the script block that will prevent the final HTML from recurring:
Copy Code code as follows:

if (Elem.parentnode)

Finally, in the Globaleval method, the Head.removechild (script) is found by inserting the script tag into the head immediately after it has been inserted, as well as avoiding the generation of duplicate script blocks in the head area because of the repeated execution of the HTML (value) method. This removal does not affect the execution of the script, nor does it erase the associated variable values in the script block. Obviously, if you want to look at the final results of HTML (data), such as what script blocks are inserted into the head, you can temporarily annotate that line of code.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.