jquery load() strips script tags - workaround?

£可爱£侵袭症+ 提交于 2019-11-26 11:35:06

问题


Does anyone know of a work around for jquery .load() stripping out the script tags loaded from external content?

There\'s a lot of documentation of the fact that this happens but after something like 4 hours searching the net I can\'t find a work around?

I\'m loading dynamically generated divs - similar to a page of search results - and need to bind a .click() to an element within each dynamically generated div. I\'ve a php file that does the html generation work and returns all the html as a string however I can\'t bind the jquery .click() as the script tags containing the jquery function get stripped out.

here\'s the code that loads the external content by calling the php file...

$(\"#titles_wrap\").load(\"m_scripts/m_php/titles_loader.php\", function(){
                                                                $..some code
                                                                });

and here\'s the loop from the php file that generates the divs (this works fine)...

$tag1=\'<script type=\"text/javascript\">\';
$tag2=\'</script>\';

while($result_array = mysql_fetch_array($result)) {

            if($i2<=($titles_total)){

                $_SESSION[\'titles_string\'] .= \'<li id=\"listItem_\'.$i2.\'\">

                                                <div id=\"titles_list_item\">

                                                    <div id=\"titles_list_image_box\" style=\"background-image: url(../../images/thumbs_test/\'.$result_array[0].\'); background-repeat: no-repeat; \">\'.($i2+1).\'</div>
                                                    <div id=\"title_php_loader\"></div>
                                                        <div id=\"title_info_wrap\">

                                                        <div id=\"title_current\"><span class=\"title_current_grey\" >current title: </span><br>\'.$result_array[1].\'
                                                            </div>

                                                                <div id=\"title_form_wrap\">
                                                                    <span class=\"title_current_grey\" >new title: </span><br><input name=\"title_input_\'.$i2.\'\" id=\"title_input_\'.$i2.\'\" type=\"text\" class=\"title_input\"></input>
                                                                    <div id=\"title_send\" class=\"title_send_\'.$i2.\'\">GO</div>
                                                                </div>

                                                            </div>


                                                    \'.$tag1.\'
                                                    $(\".title_send_\'.$i2.\'\").click(function(){$(\"#title_php_loader\").load(\"m_scripts/m_php/title_sender.php\")})
                                                    \'.$tag2.\'

                                                </div>
                                            </li>\';
                $i2++;
                                }
            }

Sorry if this second code block is a bit on the \'overkill\' side - let me know if a simplified excerpt would be more useful. That said, you can see on the 8th from last line of the php code the jquery function that should get written into each div with a dynamically assigned selector.

Of course, it could be that there\'s other errors in the code however I\'m not going to be able to test it until I can get .load() to stop trashing it!

If anyone\'s found a solution to this - or even a workaround of limited grace - brilliant!

Thanks in advance,

Cheers,

Scott

EDIT - EDIT - EDIT - EDIT - EDIT - EDIT - EDIT - EDIT

@T.J. Crowder @Frug

Thanks for your help!

I\'ve just had a good hard look at the pages involved in your demo and yes, I see you\'ve got it working. Seems amazing cos there they are - those script tags and there are SO many people out there who can\'t get it to work - unfortunately I\'m one of them!

The only differences I see between your demo and my code situation was

1) no type declaration in the opening script tag,

2) you\'re loading a page with script tags as part of the DOM, whereas I was loading php string output (I really don\'t think this matters tho\', eh? By the time it hits the client it all comes to the same thing, no?)

3), your .load call was fetching a whole page whereas mine was returning only elements. I\'ve since changed the output string to include all , and tags but grrrrrr...I still can\'t get dem damn script tags to show up in the DOM.

Any suggestions? There\'s loads I don\'t know about so could be anything! thanks S


回答1:


jQuery load doesn't strip out script tags (example), and there are no script tags in the content you're returning from your PHP script. There is some JavaScript, but it's not correctly embedded in script tags and so it's not being recognized by the browser.

If you want the JavaScript in this:

...
'.$tag1.'
$(".title_send_'.$i2.'").click(function(){$("#title_php_loader").load("m_scripts/m_php/title_sender.php")})
'.$tag2.'
...

to be recognized as JavaScript, put it in a script tag.

...
'.$tag1.'
<script>"$(".title_send_'.$i2.'").click(function(){$("#title_php_loader").load("m_scripts/m_php/title_sender.php")})</script>
'.$tag2.'
...

...or better yet, use a single script tag at the end of the content to hook things up, or the callback on the load function.


Update: Re your edit:

1) no type declaration in the opening script tag,

Doesn't matter, see this updated example. The browser interprets the script tag according to the same rules it always applies.

2) you're loading a page with script tags as part of the DOM, whereas I was loading php string output (I really don't think this matters tho', eh? By the time it hits the client it all comes to the same thing, no?)

Right, it all comes to the same thing once it gets to the browser.

3), your .load call was fetching a whole page whereas mine was returning only elements. I've since changed the output string to include all , and tags but grrrrrr...I still can't get dem damn script tags to show up in the DOM.

My example is just loading a snippet, not a full page.

I don't know why yours isn't working. I wondered if it related to multiple script elements being output in a loop, or the fact you were hooking up a click handler, but it's not either of those.

There's nothing for it but to take your non-working example and peel layers away bit by bit until you find the part that, when you remove it, lets it start working. Fundamentally, again, it's not that using load makes the scripts not work (regardless of how many people you find who think that's the case; it's a big world, there are lots of people who think nearly anything). You have to let go of the idea that this is related to jQuery's load function doing anything to the scripts; it probably isn't.

The key to debugging this kind of thing really is simplify, simplify, simplify. make sure the HTML being returned by the server for the ajax calls looks the way you think it does (no weird quotes or something). Try to do it with static pages. Etc.




回答2:


Update now, which you can find on the jQuery doc site:

http://api.jquery.com/load/

It DOES strip tags only if you call load with a specific suffixed selector..

Script Execution

When calling .load() using a URL without a suffixed selector expression, the content is passed to .html() prior to scripts being removed. This executes the script blocks before they are discarded. If .load() is called with a selector expression appended to the URL, however, the scripts are stripped out prior to the DOM being updated, and thus are not executed. An example of both cases can be seen below:

Here, any JavaScript loaded into #a as a part of the document will successfully execute. 1

$('#a').load('article.html');

However, in the following case, script blocks in the document being loaded into #b are stripped out and not executed: 1

$('#b').load('article.html #target');



回答3:


This thread is a bit older now, but I found a workaround for the $.load + selector + <script> issue/feature which I would like to share. Maybe it will be helpful to someone. Instead of $.load, I use this:

$.ajax({
    url: '/some/url',
    success: function(html) {
        var content = $('<div />').html(html).find('#my-custom-selector');
        $('#container-to-place-html-in').html(content);
    }
});

Cheers, Alex




回答4:


Can you please confirm if it is stripping out the scripts or the event bind isn't working? However, I think you can change the approach a little bit. First modify your script like

$("#titles_wrap").load("m_scripts/m_php/titles_loader.php", function(){
                                                                $..some code
                                                                $("[class^='title_send_']").click(function(){$("#title_php_loader").load("m_scripts/m_php/title_sender.php")});
                                                                });

Then remove the script part from php code

while($result_array = mysql_fetch_array($result)) {

            if($i2<=($titles_total)){

                $_SESSION['titles_string'] .= '<li id="listItem_'.$i2.'">

                                                <div id="titles_list_item">

                                                    <div id="titles_list_image_box" style="background-image: url(../../images/thumbs_test/'.$result_array[0].'); background-repeat: no-repeat; ">'.($i2+1).'</div>
                                                    <div id="title_php_loader"></div>
                                                        <div id="title_info_wrap">

                                                        <div id="title_current"><span class="title_current_grey" >current title: </span><br>'.$result_array[1].'
                                                            </div>

                                                                <div id="title_form_wrap">
                                                                    <span class="title_current_grey" >new title: </span><br><input name="title_input_'.$i2.'" id="title_input_'.$i2.'" type="text" class="title_input"></input>
                                                                    <div id="title_send" class="title_send_'.$i2.'">GO</div>
                                                                </div>

                                                            </div>
                                                </div>
                                            </li>';
                $i2++;
                                }
            }



回答5:


Why can't you use the callback function to bind the events rather than inlining it on your php page?

There might be a way to work around that but I wouldn't inline it in the first place which is why you're not finding others doing it. If you put binds in the callback they will attach when it's loaded.




回答6:


It sucks I know but one thing you can do is write something like within the html being loaded then after you .ajax or .load method in the callback do a string replace -> html = html.replace( /lscript/g, 'script' );

something to that effect should pulled the tag as an un-excuted tag.

hope that helps :)



来源:https://stackoverflow.com/questions/6036870/jquery-load-strips-script-tags-workaround

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!