HTML 和 Javascript 的高级递归引号嵌入

Advanced Recursive Quote Embedding for HTML and Javascript

提问人:erixoltan 提问时间:3/31/2023 更新时间:4/1/2023 访问量:28

问:

我有一个程序,可以让我展示相同的代码在多种编程语言中的样子。我正在将它编译为 HTML 中的网页,该网页使用按钮 onclick 处理程序将代码切换到用户想要查看的任何语言。由于复杂的嵌入问题,它失败了。我想我正确地转义了嵌入的字符,但似乎它们正在被解释,并且导致了引号嵌入问题。

下面是一个无法正常工作的按钮示例。

<button onclick="code_box('Example_1','&#60;&#63;php\n# Main Program Body\n echo &#39;Hello, World!&#39;, &#34;\n&#34;;\n\n&#63;&#62;\n')">PHP</button>

我的所有其他按钮都在工作,并且在大多数情况下,该过程都很顺利。所以我知道这不是由 code_box 函数或周围的 html 代码中的错误引起的。我认为(这只是一个猜测)转义字符正在被Firefox解释,并且因为它们包含对HTML有意义的字符,因此导致了引号嵌入问题。如果是这样的话,那么我就不知道如何解决这个问题了。

作为参考,这里是上面按钮嵌入的PHP代码。

<?php
# Main Program Body
    echo 'Hello, World!', "\n";

?>

为了提供更大的上下文,这里是其他按钮工作的完整示例,但此按钮不起作用。其他一切都有效,在我弄清楚这一点之前,我无法继续添加语言。

当我单击PHP按钮时,没有任何反应。当我单击任何其他按钮时,它们会按预期工作。我尝试从按钮代码中删除所有转义的 HTML 实体,它有效,但当然代码缺少所有这些字符。

这是在一长串调试的最后,我让它变得越来越健壮,直到它看起来万无一失,但它仍然不起作用。

提前感谢您的任何帮助!

    function code_box(Name, Text)
    {
        var Element = document.getElementById(Name);
        Element.innerHTML = Text;
    }
</script></head><body>
<div>
<button onclick="code_box('Example_1','module Hello\n{\n    main\n    {\n        write &#34;Hello, World!&#34; line;\n    }\n}')">goalspell</button>
<button onclick="code_box('Example_1','if __name__ == &#34;__main__&#34;:\n    print(&#34;Hello, World!&#34;)\n\n')">Python</button>
<button onclick="code_box('Example_1','/* Main Program Body */\nlet [_node, _code, ] = process.argv;\nconsole.log(&#34;Hello, World!&#34;);')">Javascript</button>
<button onclick="code_box('Example_1','&#60;&#63;php\n# Main Program Body\n    echo &#39;Hello, World!&#39;, &#34;\n&#34;;\n\n&#63;&#62;\n')">PHP</button>
<button onclick="code_box('Example_1','Hello\nHello ; Hello module.\nMAIN() ; main program\n W &#34;Hello, World!&#34;,!\n Q\n\n\n')">MUMPS</button>
<div class="codebox" id="Example_1">module Hello
{
    main
    {
        write "Hello, World!" line;
    }
}</div></div>```
JavaScript HTML 引号嵌入

评论

0赞 Pointy 3/31/2023
如果您在 JavaScript 中对事件处理程序进行编码,并将它们添加到元素中,而不是使用 HTML 属性,则代码将更加清晰且易于维护。.addEventListener()
0赞 erixoltan 4/1/2023
通过检查上述示例生成的 HTML,我获得了额外的见解。有问题的按钮标记的外部 HTML 如下所示: 这意味着浏览器正在插入我的 HTML 转义字符,这产生了问题。这就是为什么它在视觉上看起来如此正确,但行为却如此错误!<button onclick="code_box(`Example_1`,'<?php\n# Main Program Body\n echo 'Hello, World!', &quot;\n&quot;;\n\n?>\n')">PHP</button>

答:

1赞 Quentin 3/31/2023 #1

不要试图用手写出所有的转义。使用旨在为您正在使用的语言转义数据的函数来执行此操作。

<?php
    $string = "The string
you want to show
which can have just about
any literal characters in it
although you need to take care
of \$ and \" as they are 
special in PHP!";

    # You can generate JS source code using json_encode since JSON is
    # more-or-less a subset of JS.
    $javascript_literal = json_encode($string);

    # Then write your JavaScript expression and convert it to HTML
    $javascript_expression = "code_box('Example_1', $javascript_literal);"
    $html_attribute_value = htmlspecialchars($javascript_expression);
?>
<button onclick="<?php echo $html_attribute_value ?>">Value</button>

评论

0赞 erixoltan 3/31/2023
我同意你提出的基本观点。实际上,我正在做一些超出您建议的通用性步骤,并且为了简单起见,我仅显示生成的 Javascript。无论如何,您的 PHP 示例仍会将文本字符串放在带引号的字符串中,因此仍然必须正确转义。您的 PHP 变量 $html_attribute_value 的值仍将由 Web 浏览器解释,因此我在您的答案中没有看到解决我的核心问题的方法。
0赞 Quentin 3/31/2023
@erixoltan — 区别在于它将被正确引用。浏览器的 HTML 解析器将解析属性值,然后将其传递给 JavaScript 解析器,后者会将其解析为 JavaScript,并且会正确解析。您的方法(无论是您的问题中显示的显然是手动的方法,还是您在评论中提到的类似我的建议但做错了的方法)导致尝试将字符放入 JavaScript 字符串文本中,该字符串由字符分隔,而不为 JavaScript 转义它们。''
0赞 erixoltan 4/1/2023
我感谢您真诚的帮助,您的方法很好。我努力尝试了您发布的PHP代码,但未能解决问题。如果我使用的是 PHP,那么我会更详细地追求这个想法。我正在使用一个代码生成器,它获取用我的编程语言编写的代码并将其编译为多种目标语言。然后,转换例程将生成的目标代码转义为 Javascript 可嵌入的字符串。该代码需要位于 HTML 元素内,因此它随后会进一步转义到 HTML 安全字符实体中。为了简单起见,我展示了生成的 HTML。
0赞 Quentin 4/1/2023
@erixoltan — 然后那对转换例程被破坏。我们无法使用您提供的信息修复它们。
0赞 erixoltan 4/1/2023
是的,这正是我注意到我所犯的非常简单的错误时正在做的事情!
0赞 erixoltan 4/1/2023 #2

有时你太担心一些超级先进的东西,你看不到一些明显的东西!

在这种情况下,我正在使用代码生成器,在那里我不遗余力地确保我正确地嵌入了 HTML 和 Javascript 字符。即使我确定嵌入的字符是正确的,我也看到代码不起作用。我尝试了至少十种不同的(可能是正确的)方法来解决这个问题。

没有任何帮助。

我很想责怪浏览器。然后,当我第一百次回到调试器中挠头时,我注意到我做错了什么。

function code_box(Name, Text)
{
    var Element = document.getElementById(Name);
    Element.innerHTML = Text;
}

这段代码在我的原始帖子中很简单,它设置的是 innerHTML 而不是 innerText。这意味着代码需要额外转义一段时间才能正常工作。我没有这样做,而是进行了以下更改。

更正后的代码如下。

function code_box(Name, Text)
{
    var Element = document.getElementById(Name);
    Element.innerText = Text;
}

解决了整个问题。

真是如释重负!!