• html 转义处理


    比如要把:<span>test</span> 这段代码当做文本原样输出在页面上,如果按照正常的方式,肯定会被转义,在页面上只能看到 text。那么要想达到预想的效果,应该怎么办呢?

    在学习 html 标签时,知道如果要把 代码 原样输出,可以用标签 pre + code 处理。但这种方式不能处理:html 标签。

    1. 借助 vue 框架,可以这么做实现:

    <template>
         <p v-html="html" />
    </template>
    
    <script>
        export default {
            data () {
                return {
                    html: '<span>test</span>'
                }
            }
        }
    </script>
    

    2. 借助 react 框架,可以这么实现:

    import React, { PureComponent } from 'react'
    
    class Test extends PureComponent {
      constructor (props) {
          super(props)
          
          this.state = {
             html: '<span>test</span>'
          }
      }
        
      render () {
       const { content } = this.state
    
        return (
          <div>
            <p dangerouslySetInnerHTML={{__html: content}} />
          </div>
        )
      }
    }
    

    3. 如果想只用一个 html 标签就实现,可能吗?答案是可能的,可以用 xmp 标签。这个标签的作用:会将内容当做字符串输出。

    <xmp><span>test</span></xmp>
    

    不过,这个标签被W3C废弃了,但各大浏览器依然支持该标签。为什么被废弃呢?被废弃,肯定有被废弃的缘由的。如果一定要用这个标签,需注意:

    • 若模板中包含标签会造成标签结束符混乱的问题,因此通过该方式存放模板时,不能包含结束标签;
    • xmp元素必须作为body的子孙元素。

    4. 那么不借助xmp标签或框架的能力,如何自己实现呢?

    // html 转义处理
    function htmlEncode (text) {
        var isHtml = /[x00`><"'&]/;
        var htmlEncode = /[x00`><"'&]/g;
        return text != null ? isHtml.test(text) && ("" + text).replace(htmlEncode, getCharEntity) || text : "";
    
        function getCharEntity (ch) {
            var charEntities = {
                "&": "&amp;",
                "<": "&lt;",
                ">": "&gt;",
                "x00": "&#0;",
                "'": "&#39;",
                '"': "&#34;",
                "`": "&#96;"
            };
            return charEntities[ch] || (charEntities[ch] = "&#" + ch.charCodeAt(0) + ";");
        }
    };
    
    let htmlCon = '<span>test</span>';
    document.querySelector('#html_con').innerHTML = htmlEncode(htmlCon);
    

    5. 特地去看了 vuereact 源码,想看看它们都是怎么实现的。但只找到 react 中是怎么实现的,vue 目录太多也比较绕,没找到。

    node-modeles/react-dom/cjs/react-dom-server.browser.development.js 中 631 行。

    // code copied and modified from escape-html
    /**
     * Module variables.
     * @private
     */
    
    var matchHtmlRegExp = /["'&<>]/;
    
    /**
     * Escapes special characters and HTML entities in a given html string.
     *
     * @param  {string} string HTML string to escape for later insertion
     * @return {string}
     * @public
     */
    
    function escapeHtml(string) {  
      var str = '' + string;
      var match = matchHtmlRegExp.exec(str);
    
      if (!match) {
        return str;
      }
    
      var escape = void 0;
      var html = '';
      var index = 0;
      var lastIndex = 0;
    
      for (index = match.index; index < str.length; index++) {
        switch (str.charCodeAt(index)) {
          case 34:
            // "
            escape = '&quot;';
            break;
          case 38:
            // &
            escape = '&amp;';
            break;
          case 39:
            // '
            escape = '&#x27;'; // modified from escape-html; used to be '&#39'
            break;
          case 60:
            // <
            escape = '&lt;';
            break;
          case 62:
            // >
            escape = '&gt;';
            break;
          default:
            continue;
        }
    
        if (lastIndex !== index) {
          html += str.substring(lastIndex, index);
        }
    
        lastIndex = index + 1;
        html += escape;
      }
    
      return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
    }
    // end code copied and modified from escape-html
    
    /**
     * Escapes text to prevent scripting attacks.
     *
     * @param {*} text Text value to escape.
     * @return {string} An escaped string.
     */
    function escapeTextForBrowser(text) {
      if (typeof text === 'boolean' || typeof text === 'number') {
        // this shortcircuit helps perf for types that we know will never have
        // special characters, especially given that this function is used often
        // for numeric dom ids.
        return '' + text;
      }
      return escapeHtml(text);
    }
    
    /**
     * Escapes attribute value to prevent scripting attacks.
     *
     * @param {*} value Value to escape.
     * @return {string} An escaped string.
     */
    function quoteAttributeValueForBrowser(value) {
      return '"' + escapeTextForBrowser(value) + '"';
    }
    

    这部分源码,还是比如容易看懂呢。

    总结:html 转义,主要就是将 "'&<> 这几个特殊字符转换为 html 实体。

    延伸:预防 xss 攻击:

    • 对用户输入进行转义
    • 获取内容后,反转义并domParse,过滤不安全标签及属性,进行xss拦截
      • 不安全标签:style、link、script、iframe、frame、img
      • 不安全属性:onerror、onclick等
  • 相关阅读:
    PowerDesigner反向工程操作步骤 以PowerDesigner15为例
    RegularExpressionValidator控件中正则表达式用法
    在C#中进行数据纵向不定行转横向列,多条信息成一行,例如员工薪资信息
    Oracle常见等待事件说明
    ORACLE 绑定变量用法总结(转)
    Configure Oracle 11gR2 RAC 一节点执行root.sh脚本报错
    ORACLE ASH/AWR
    db file sequential read 事件的优化(一)
    Redo Log Buffer的大小设置转载
    Oracle 判断 并 手动收集 统计信息 脚本
  • 原文地址:https://www.cnblogs.com/EnSnail/p/10313458.html
Copyright © 2020-2023  润新知