首页 文章

使用jQuery转义HTML字符串

提问于
浏览
553

有谁知道在jQuery中从字符串中转义HTML的简单方法?我需要能够传递任意字符串并将其正确转义以在HTML页面中显示(防止JavaScript / HTML注入攻击) . 我可以扩展jQuery来实现这一目标,但我目前还不了解该框架以实现这一目标 .

24 回答

  • 24
    function htmlEscape(str) {
        var stringval="";
        $.each(str, function (i, element) {
            alert(element);
            stringval += element
                .replace(/&/g, '&')
                .replace(/"/g, '"')
                .replace(/'/g, ''')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(' ', '-')
                .replace('?', '-')
                .replace(':', '-')
                .replace('|', '-')
                .replace('.', '-');
        });
        alert(stringval);
        return String(stringval);
    }
    
  • 0

    简单的JavaScript转义示例:

    function escapeHtml(text) {
        var div = document.createElement('div');
        div.innerText = text;
        return div.innerHTML;
    }
    
    escapeHtml("<script>alert('hi!');</script>")
    // "&lt;script&gt;alert('hi!');&lt;/script&gt;"
    
  • -2

    很容易使用下划线:

    _.escape(string)
    

    Underscore是一个实用程序库,它提供了许多本机js也没有lodash的功能,这些功能与下划线相同,但被重写为更高性能 .

  • 3

    如果你有underscore.js,请使用 _.escape (比上面发布的jQuery方法更有效):

    _.escape('Curly, Larry & Moe'); // returns: Curly, Larry &amp; Moe
    
  • 0

    如果你不防止再次逃脱,所有解决方案都是无用的,例如,大多数解决方案都会继续逃避 &&amp; .

    escapeHtml = function (s) {
        return s ? s.replace(
            /[&<>'"]/g,
            function (c, offset, str) {
                if (c === "&") {
                    var substr = str.substring(offset, offset + 6);
                    if (/&(amp|lt|gt|apos|quot);/.test(substr)) {
                        // already escaped, do not re-escape
                        return c;
                    }
                }
                return "&" + {
                    "&": "amp",
                    "<": "lt",
                    ">": "gt",
                    "'": "apos",
                    '"': "quot"
                }[c] + ";";
            }
        ) : "";
    };
    
  • 2

    如果你正在逃避HTML,那么我只能想到三个非常必要的东西:

    html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
    

    根据您的使用情况,您可能还需要执行 "&quot; 之类的操作 . 如果列表足够大,我只使用一个数组:

    var escaped = html;
    var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g, "&gt;"], [/"/g, "&quot;"]]
    for(var item in findReplace)
        escaped = escaped.replace(findReplace[item][0], findReplace[item][1]);
    

    encodeURIComponent() 只会为URL而不是HTML转义它 .

  • 32

    试试Underscore.string lib,它适用于jQuery .

    _.str.escapeHTML('<div>Blah blah blah</div>')
    

    输出:

    '&lt;div&gt;Blah blah blah&lt;/div&gt;'
    
  • 35

    这是一个很好的安全例子......

    function escapeHtml(str) {
        if (typeof(str) == "string"){
            try{
                var newStr = "";
                var nextCode = 0;
                for (var i = 0;i < str.length;i++){
                    nextCode = str.charCodeAt(i);
                    if (nextCode > 0 && nextCode < 128){
                        newStr += "&#"+nextCode+";";
                    }
                    else{
                        newStr += "?";
                    }
                 }
                 return newStr;
            }
            catch(err){
            }
        }
        else{
            return str;
        }
    }
    
  • 543

    我写了一个很小的功能来做到这一点 . 它只能逃脱 "&<> (但通常这就是你所需要的全部) . 它比早期提出的解决方案稍微优雅一点,它只使用一个 .replace() 进行所有转换 . ( EDIT 2: 降低代码复杂性使得功能更小更整洁,如果您对原始代码感到好奇,请参阅此答案的结尾 . )

    function escapeHtml(text) {
        'use strict';
        return text.replace(/[\"&<>]/g, function (a) {
            return { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' }[a];
        });
    }
    

    这是普通的Javascript,没有使用jQuery .

    逃避/和'也

    Edit in response to mklement's comment.

    上述功能可以轻松扩展为包含任何字符 . 要指定要转义的更多字符,只需将它们插入正则表达式中的字符类(即 /[...]/g 内)和 chr 对象中的条目 . ( EDIT 2: 也以同样的方式缩短了这个功能 . )

    function escapeHtml(text) {
        'use strict';
        return text.replace(/[\"&'\/<>]/g, function (a) {
            return {
                '"': '&quot;', '&': '&amp;', "'": '&#39;',
                '/': '&#47;',  '<': '&lt;',  '>': '&gt;'
            }[a];
        });
    }
    

    请注意上面使用 &#39; 作为撇号(可能已经使用了符号实体 &apos; - 它在XML中定义,但最初未包含在HTML规范中,因此可能不受所有浏览器支持 . 请参阅:Wikipedia article on HTML character encodings) . 我还记得在某处读取使用十进制实体比使用十六进制更广泛支持,但我现在似乎无法找到它的来源 . (并且不会有很多不支持十六进制实体的浏览器 . )

    Note:/' 添加到转义字符列表并不是很有用,因为它们在HTML中没有任何特殊含义,也不需要转义 .

    原始的escapeHtml函数

    EDIT 2: 原始函数使用变量( chr )来存储 .replace() 回调所需的对象 . 这个变量还需要一个额外的匿名函数来限定它,使函数(不必要地)变得更大更复杂 .

    var escapeHtml = (function () {
        'use strict';
        var chr = { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };
        return function (text) {
            return text.replace(/[\"&<>]/g, function (a) { return chr[a]; });
        };
    }());
    

    我还没有测试过哪两个版本更快 . 如果您这样做,请随时在此处添加有关它的信息和链接 .

  • 26
    function htmlDecode(t){
       if (t) return $('<div />').html(t).text();
    }
    

    奇迹般有效

  • 5

    如果你正在使用正则表达式路线,那么上面的tghw例子就会出错 .

    <!-- WON'T WORK -  item[0] is an index, not an item -->
    
    var escaped = html; 
    var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g,"&gt;"], [/"/g,
    "&quot;"]]
    
    for(var item in findReplace) {
         escaped = escaped.replace(item[0], item[1]);   
    }
    
    
    <!-- WORKS - findReplace[item[]] correctly references contents -->
    
    var escaped = html;
    var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g, "&gt;"], [/"/g, "&quot;"]]
    
    for(var item in findReplace) {
         escaped = escaped.replace(findReplace[item[0]], findReplace[item[1]]);
    }
    
  • 4

    This answer提供了jQuery和普通的JS方法,但这是最短的而不使用DOM:

    unescape(escape("It's > 20% less complicated this way."))
    

    转义字符串: It%27s%20%3E%2020%25%20less%20complicated%20this%20way.

    如果逃脱的空间打扰你,请尝试:

    unescape(escape("It's > 20% less complicated this way.").replace(/%20/g, " "))
    

    转义字符串: It%27s %3E 20%25 less complicated this way.

    不幸的是, escape() 函数是deprecated in JavaScript version 1.5 . encodeURI()encodeURIComponent() 是替代品,但它们忽略了 ' ,因此最后一行代码将变为:

    decodeURI(encodeURI("It's > 20% less complicated this way.").replace(/%20/g, " ").replace("'", '%27'))
    

    所有主流浏览器仍然支持短代码,鉴于旧网站的数量,我怀疑这将很快改变 .

  • 1

    2个简单的方法,需要NO JQUERY ......

    你可以在你的字符串中 encode all characters 像这样:

    function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
    

    或者只是 target the main characters 担心 & ,换行符, <>"' 喜欢:

    function encode(r){
    return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
    }
    
    var myString='Encode HTML entities!\n"Safe" escape <script></'+'script> & other tags!';
    
    test.value=encode(myString);
    
    testing.innerHTML=encode(myString);
    
    /*************
    * \x26 is &ampersand (it has to be first),
    * \x0A is newline,
    *************/
    
    <p><b>What JavaScript Generated:</b></p>
    
    <textarea id=test rows="3" cols="55"></textarea>
    
    <p><b>What It Renders Too In HTML:</b></p>
    
    <div id="testing">www.WHAK.com</div>
    
  • 1

    您可以使用vanilla js轻松完成 .

    只需在文档中添加文本节点即可 . 它将被浏览器转义 .

    var escaped = document.createTextNode("<HTML TO/ESCAPE/>")
    document.getElementById("[PARENT_NODE]").appendChild(escaped)
    
  • 30

    经过最后的测试,我可以推荐 fastest 和完全 cross browser 兼容的 native javaScript (DOM)解决方案:

    function HTMLescape(html){
        return document.createElement('div')
            .appendChild(document.createTextNode(html))
            .parentNode
            .innerHTML
    }
    

    如果你重复多次,你可以用一次准备好的变量来做:

    //prepare variables
    var DOMtext = document.createTextNode("test");
    var DOMnative = document.createElement("span");
    DOMnative.appendChild(DOMtext);
    
    //main work for each case
    function HTMLescape(html){
      DOMtext.nodeValue = html;
      return DOMnative.innerHTML
    }
    

    看看我的最终表现comparisonstack question) .

  • 15

    如果要将此信息保存在 database 中,使用 client-side 脚本转义HTML是错误的,这应该在 server 中完成 . 否则很容易绕过您的XSS保护 .

    To make my point clear, here is a exemple using one of the answers:

    假设您正在使用函数escapeHtml从您的博客中的评论中转义Html然后将其发布到您的服务器 .

    var entityMap = {
        "&": "&amp;",
        "<": "&lt;",
        ">": "&gt;",
        '"': '&quot;',
        "'": '&#39;',
        "/": '&#x2F;'
      };
    
      function escapeHtml(string) {
        return String(string).replace(/[&<>"'\/]/g, function (s) {
          return entityMap[s];
        });
      }
    

    用户可以:

    • 编辑POST请求参数并用javascript代码替换注释 .

    • 使用浏览器控制台覆盖escapeHtml函数 .

    如果用户将此代码段粘贴到控制台中,则会绕过XSS验证:

    function escapeHtml(string){
       return string
    }
    
  • 402

    escape()unescape() 用于对URL的字符串进行编码/解码,而不是HTML .

    实际上,我使用以下代码片段来完成不需要任何框架的技巧:

    var escapedHtml = html.replace(/&/g, '&amp;')
                          .replace(/>/g, '&gt;')
                          .replace(/</g, '&lt;')
                          .replace(/"/g, '&quot;')
                          .replace(/'/g, '&apos;');
    
  • 24

    由于您使用的是jQuery,因此您只需设置元素的text属性:

    // before:
    // <div class="someClass">text</div>
    var someHtmlString = "<script>alert('hi!');</script>";
    
    // set a DIV's text:
    $("div.someClass").text(someHtmlString);
    // after: 
    // <div class="someClass">&lt;script&gt;alert('hi!');&lt;/script&gt;</div>
    
    // get the text in a string:
    var escaped = $("<div>").text(someHtmlString).html();
    // value: 
    // &lt;script&gt;alert('hi!');&lt;/script&gt;
    
  • 177

    我意识到我参加这个派对有多晚了,但我有一个非常简单的解决方案,不需要jQuery .

    escaped = new Option(unescaped).innerHTML;
    

    编辑:这不会逃避报价 . 引用需要转义的唯一情况是内容是否将内联粘贴到HTML字符串中的属性 . 我很难想象一个这样做的好例子 .

    编辑2:如果性能至关重要,最高性能解决方案(约50%)仍然是一系列正则表达式替换 . 现代浏览器将检测到正则表达式不包含运算符,只包含字符串,并将所有正则表达式折叠为单个运算 .

  • 58
    (function(undefined){
        var charsToReplace = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;'
        };
    
        var replaceReg = new RegExp("[" + Object.keys(charsToReplace).join("") + "]", "g");
        var replaceFn = function(tag){ return charsToReplace[tag] || tag; };
    
        var replaceRegF = function(replaceMap) {
            return (new RegExp("[" + Object.keys(charsToReplace).concat(Object.keys(replaceMap)).join("") + "]", "gi"));
        };
        var replaceFnF = function(replaceMap) {
            return function(tag){ return replaceMap[tag] || charsToReplace[tag] || tag; };
        };
    
        String.prototype.htmlEscape = function(replaceMap) {
            if (replaceMap === undefined) return this.replace(replaceReg, replaceFn);
            return this.replace(replaceRegF(replaceMap), replaceFnF(replaceMap));
        };
    })();
    

    没有全局变量,一些内存优化 . 用法:

    "some<tag>and&symbol©".htmlEscape({'©': '&copy;'})
    

    结果是:

    "some&lt;tag&gt;and&amp;symbol&copy;"
    
  • 15
    $('<div/>').text('This is fun & stuff').html(); // "This is fun &amp; stuff"
    

    资料来源:http://debuggable.com/posts/encode-html-entities-with-jquery:480f4dd6-13cc-4ce9-8071-4710cbdd56cb

  • 10

    这是一个干净,清晰的JavaScript函数 . 它会将诸如“少数<许多”之类的文本转换为“少数几个” .

    function escapeHtmlEntities (str) {
      if (typeof jQuery !== 'undefined') {
        // Create an empty div to use as a container,
        // then put the raw text in and get the HTML
        // equivalent out.
        return jQuery('<div/>').text(str).html();
      }
    
      // No jQuery, so use string replace.
      return str
        .replace(/&/g, '&amp;')
        .replace(/>/g, '&gt;')
        .replace(/</g, '&lt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&apos;');
    }
    
  • 1

    还有the solution from mustache.js

    var entityMap = {
      '&': '&amp;',
      '<': '&lt;',
      '>': '&gt;',
      '"': '&quot;',
      "'": '&#39;',
      '/': '&#x2F;',
      '`': '&#x60;',
      '=': '&#x3D;'
    };
    
    function escapeHtml (string) {
      return String(string).replace(/[&<>"'`=\/]/g, function (s) {
        return entityMap[s];
      });
    }
    
  • -2

    我已经增强了mustache.js示例,将 escapeHTML() 方法添加到字符串对象中 .

    var __entityMap = {
        "&": "&amp;",
        "<": "&lt;",
        ">": "&gt;",
        '"': '&quot;',
        "'": '&#39;',
        "/": '&#x2F;'
    };
    
    String.prototype.escapeHTML = function() {
        return String(this).replace(/[&<>"'\/]/g, function (s) {
            return __entityMap[s];
        });
    }
    

    这样很容易使用 "Some <text>, more Text&Text".escapeHTML()

相关问题