【问题标题】:Escape angle brackets with JS用JS转义尖括号
【发布时间】:2017-02-19 22:08:27
【问题描述】:

问题被完全重写为更紧凑和清晰的形式。

当我用sn-ps编写HTML文档时,我不想手动将每个<更改为<。在我看来,最明显的方法是使用 JS 来完成这项任务,如下所示。但是,它不起作用。

如何解决?

Fiddle

<head>
    <style>
        body {
            width: 500px;
        }
    </style>
    <script>
        window.onload = function() {
            var pre = document.querySelector("#html-example");
            pre.innerHTML = pre.innerHTML
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;');
        };
    </script>
</head>
<body>
    <h1>
        Chapter 1
    </h1>
    <p>
        Here is the first tutorial of HTML for total beginners.
        Typical HTML contains of 2 main parts: head and body.
        Here is an exmaple of how it looks:
    </p>
    <pre id="html-example" style="background-color: aliceblue;">
<head>
    Head content goes here. Only very technical things
</head>
<body>
    Body content goes here. Not necessary very technical.
    For example, something about cats.
</body>
    </pre>
    <p>
        ..............
    </p>
</body>

当前结果:

想要的结果:

【问题讨论】:

  • “我想了解如何修复脚本方式的疏忽。” 不能;不要这样做。这是完全不安全的,也没有充分的理由。
  • @Ryan 好的,但是我怎样才能完成我的任务呢?我有静态 HTML 文档,我在其中撰写有关 HTML 和 JS 的文章供我个人本地使用。显然,这些文章包含 HTML sn-ps 及其描述。除了手动替换每个&amp;lt; 之外,有没有办法编写它?如果没有 JS 方式,那么好吧,也许我应该安装一些简单的服务器,它会被 PHP 或其他服务器端语言转义?在 StackOverflow,我们编写了很多 sn-ps 而不用 esaping,并且所有这些代码都成功且安全地发布到了网络上。
  • Stack Overflow 使用 Markdown;如果你愿意,你也可以这样做,使用像 Jekyll 这样的静态网站生成器。
  • 好吧,我了解 Markdown。但也有其他关于编程的网站和论坛,有时他们不使用 Markdown。尽管如此,用户在这些网站上发布的代码仍然成功逃脱。如果我不能(或不应该)用 JS 完成它,我想知道在大多数情况下如何实现它。
  • 使用动态服务器端渲染,是的,或者通过像前面提到的静态站点生成器那样进行预渲染(这似乎适合您的情况)。

标签: javascript jquery dom escaping


【解决方案1】:

这完全不是最好的方法,但我认为它比在&lt;&gt; 上进行查找/替换更好,并且绝对优于任何依赖于 javascript 中的 HTML 解析的解决方案(永远不要这样做......)。

在您编写的 HTML 文档中,您可以包含使用 &lt;script type="text/html"&gt; 标签而不是您现在使用的 &lt;pre&gt; 标签的代码示例。

默认情况下,浏览器不会对这种类型的标签做任何事情。但在 javascript 中,您可以像使用 document.querySelector 或任何其他 DOM api 方法一样选择任何其他元素。

这意味着在文档加载时,您可以将所有 &lt;script&gt; 标签替换为带有文本节点的 &lt;pre&gt; 标签:

Array.from(document.querySelectorAll(".js-example"))
  .forEach(el => {
    const textNode = document.createTextNode(el.innerHTML)
    const pre = document.createElement("pre");

    pre.style.backgroundColor = "aliceblue";
    pre.appendChild(textNode);

    el.parentElement.insertBefore(pre, el);
    el.parentElement.removeChild(el);

  })
<h1>
  Chapter 1
</h1>
<p>
  Here is the first tutorial of HTML for total beginners. Typical HTML contains of 2 main parts: head and body. Here is an exmaple of how it looks:
</p>

<script class="js-example" type="text/html">
<head>
  Head content goes here. Only very technical things
</head>

<body>
  Body content goes here. Not necessary very technical. For example, something about cats.
</body>
</script>

<p>
  ..............
</p>

<p>
  Another example:
  <script class="js-example" type="text/html">
An unclosed tag: </p>
  </script>
...
</p>

免责声明:我仅将其用于简单示例...如果这是您网站的主要目标,我将投资于更优雅的解决方案,如 cmets 中提到的。另外,我认为该解决方案不支持包含自己的 &lt;/script&gt; 标记的示例...

【讨论】:

  • 谢谢 :-) 但是为什么像我的示例中所示的简单 JS 替换不能正常工作?
  • 你的函数执行onload,这意味着它在浏览器解析你的HTML之后开始运行。 &lt;pre&gt; 标签包含 preformatted 文本,但这并不意味着浏览器会忽略其中的任何 HTML 标记。例如:如果您使用&lt;pre&gt;&lt;strong&gt;Hello&lt;/strong&gt;&lt;/pre&gt;,它仍然是粗体。当浏览器解析 &lt;pre&gt; 的内容时,它会删除任何 HTML 标记,这意味着当您的 javascript 方法启动时,没有留下任何 &lt; 字符。
猜你喜欢
  • 1970-01-01
  • 2010-09-09
  • 2014-09-15
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多