繁体   English   中英

阻止jquery ajax从脚本或html响应中执行javascript

[英]prevent jquery ajax to execute javascript from script or html response

根据文件:

如果指定了html,则在将HTML作为字符串返回之前,将执行检索到的数据中的任何嵌入式JavaScript。 同样,脚本将执行从服务器撤回的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再次执行它(如文档中所述)

Lee的答案已经充分解决了HTML响应的问题 - 除非您将HTML添加到DOM,否则嵌入在这些中的脚本实际上并不会自动执行,这与您引用的错误文档相反。

这样就会在你的问题标题中询问另一个案例 - 防止脚本响应在收到时自动执行。 您可以使用dataType设置轻松完成此操作。

$.ajax('myscript.js', {
    dataType: 'text',
    success: function (response) {
        // Do something with the response
    }
})

dataType设置为'text'将导致jQuery忽略从服务器返回的Content-Type标头,并将响应视为纯文本,从而阻止JavaScript响应的默认行为(即执行它们)。 来自(最近更正的) 文档

预处理的类型默认依赖于响应的Content-Type,但可以使用dataType选项显式设置。 如果提供了dataType选项,则将忽略响应的Content-Type标头。

...

如果指定了texthtml ,则不进行预处理。 数据只是传递给成功处理程序,并通过jqXHR对象的responseText属性提供。

在请求HTML时, jQuery.ajax 不会在返回时评估脚本。 您在问题中引用的段落实际上是文档中长期存在的错误,已于2014年4月修复 新文档有这样说(强调我的):

“html”:以纯文本形式返回HTML; 包含的脚本标记在插入DOM时进行评估。

...

如果指定了texthtml则不进行预处理。 数据只是传递给成功处理程序 ,并通过jqXHR对象的responseText属性提供。

调用时,在这种情况下会评估脚本

edit_dialog.html(response);

如果您不想在将响应插入DOM之前评估脚本,那么您应该能够执行以下操作:

edit_dialog.html($($.parseHTML(response)));

parseHTML是关键,默认情况下它会删除脚本标记。 但是,请注意parseHTML不是XXS安全的,如果您的来源未知,这仍然是一个安全问题。

这是关于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时才有效。

该文档指出,在将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
  }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM