根据文件:
如果指定了html,则检索内部的任何嵌入式JavaScript 在将HTML作为字符串返回之前执行数据。同样的, 脚本将执行从中拉回的JavaScript 服务器,然后什么也不返回。
如何防止这种情况? 我有js将修改通过ajax获得的内容。在返回html之前执行它是没有意义的,因为它没有内容可以处理(至少在我的情况下)。
我的代码:
function do_ajax(url)
{
$.ajax(
{
cache: false,
url : url,
success: function(response, status, xhr)
{
var ct = xhr.getResponseHeader("content-type") || "";
if (ct.indexOf('script') > -1) {
try {
eval(response);
}
catch(error) { }
}
else
{
var edit_dialog = $('<div class="edit_dialog" style="display:hidden"></div>').appendTo('body');
edit_dialog.html(response);
edit_dialog.dialog({ modal:true, close: function(event, ui) { $(this).dialog('destroy').remove(); } });
}
},
error:function (xhr, ajaxOptions, thrownError){
alert(xhr.status);
alert(thrownError);
}
});
}
ajax收到的脚本执行两次。首先由我在eval(响应)中,然后jquery再次执行它(如文档中所述)
答案 0 :(得分:8)
Lee's answer已经充分解决了HTML响应的问题 - 其中嵌入的脚本而不是实际上是自动执行的,除非您将HTML添加到DOM,这与您引用的错误文档相反
在你的问题标题中留下另一个案例 - 阻止脚本响应在收到时自动执行。您可以使用dataType
设置轻松完成此操作。
$.ajax('myscript.js', {
dataType: 'text',
success: function (response) {
// Do something with the response
}
})
将dataType
设置为'text'
将导致jQuery忽略从服务器返回的Content-Type
标头,并将响应视为纯文本,从而阻止JavaScript响应的默认行为(即执行它们)。来自(最近更正的)docs:
预处理的类型默认取决于响应的Content-Type,但可以使用dataType选项显式设置。如果提供了dataType选项,则将忽略响应的Content-Type标头。
...
如果指定
text
或html
,则不会进行预处理。数据只是传递给成功处理程序,并通过jqXHR
对象的responseText属性提供。
答案 1 :(得分:3)
jQuery.ajax
在请求HTML时不会评估返回的脚本。您在问题中引用的段落实际上是文档中的长期错误,fixed as of April 2014。新文档有这样说(强调我的):
“html”:以纯文本形式返回HTML;包含的脚本标记在插入DOM 时评估为。
...
如果指定了
text
或html
,则不会进行预处理。数据只是传递给成功处理程序,并通过jqXHR
对象的responseText属性提供。
在这种情况下,当您调用
时,将评估脚本edit_dialog.html(response);
如果您不想在将响应插入DOM之前评估脚本,那么您应该可以执行以下操作:
edit_dialog.html($($.parseHTML(response)));
parseHTML
是关键,默认情况下会删除脚本标记。但是,请注意parseHTML不是XXS安全的,如果您的来源未知,这仍然是一个安全问题。
答案 2 :(得分:-1)
文档指出,在将HTML作为字符串返回之前,将执行检索到的数据中的任何嵌入式Javascript 。如果你想改变你使用ajax调用检索的内容,你可以在succes属性中这样做:
$.ajax({
url: "example.html",
type: "GET",
dataType: "html",
succes: function(data){
// Example: alert(data);
// Do whatever you want with the returned data using JS or jQuery methods
}
});
答案 3 :(得分:-1)
这是关于jQuery的一个非常恼人的事情,它在响应时执行javascript。 像MooTools这样的其他框架会禁止响应中的脚本执行,除非您专门设置了要执行它们的方法,这是一种更好的方法。
我想要阻止脚本执行的唯一方法是添加自定义 dataFilter 它很容易,但我认为它应该是默认和ajax选项,以便在需要时启用脚本执行(我从来没有使用它,而其他框架默认禁用安全等。)
示例
$.ajax('uri',{
dataFilter: function(data, type)
{
type = type || 'text';
if(type=='html'||type=='text'){
/*return data.replace(/<script.*>.*?<\/script>/gi, '');*/
return data.replace(/<script.*?>([\w\W\d\D\s\S\0\n\f\r\t\v\b\B]*?)<\/script>/gi, '');
}
return data;
}
, success: function(data)
{
// whatever
}
});
**更新** 需要疯狂的正则表达式来覆盖更多的脚本标记实例
注意强> 如果dataType没有在选项中设置,那么它将在dataFilter中未定义,所以我只是将其默认为过滤器的文本 - 如果删除该行,那么只有在明确设置了dataType时它才会起作用。