无意中关闭了生成JavaScript(本身通过JavaScript调用)的PHP函数中的</script>标签

Unintentionally closing </script> tags in a PHP function which generates JavaScript (itself called via JavaScript)

本文关键字:JavaScript 函数 PHP 标签 script 调用 无意中      更新时间:2023-09-26
对于

冗长的解释表示歉意,我知道这是一个有点奇怪的问题,这就是为什么我觉得最好包含完整的上下文来描述我为什么以我的方式做事,以及为什么我(也许是错误的(觉得这种方式是必要的。

上下文

作为 Web 应用程序的一部分,我需要允许用户向文档添加注释。当用户单击链接时,他们将被重定向(通过强制性公司身份验证页面以确认其身份(到弹出窗口,他们可以在其中输入评论并单击"提交"按钮以添加其评论。

当用户单击"提交"时,我想将查询INSERT到我的 MySQL 数据库中,然后关闭弹出窗口并刷新父窗口(以便文档显示新添加的注释(。

这些元素中的任何一个都没有问题。我可以编写一个 JavaScript 函数来响应提交按钮的onclick;我可以成功查询数据库;我可以在关闭弹出窗口之前刷新父窗口。这些元素中的每一个都可以单独完美地工作。我的问题是将它们结合起来。

当我尝试从 PHP 函数中回显 JavaScript 时,它会导致问题。

步骤

  • 步骤 1 提交按钮的onclick调用 JavaScript 函数。
  • 步骤 2 此 JavaScript 函数调用 PHP 函数来查询数据库。
  • 步骤 3 JavaScript 必须在此 PHP 函数中生成,以刷新父窗口并关闭弹出窗口。

步骤 1

提交按钮的点击调用 addCommentJS((;JavaScript 函数。

echo "<input type='submit' value='Add Comment' onclick='addCommentJS(); return false;'>";

步骤 2

addCommentJS(( JavaScript 函数调用 PHP 函数 addCommentPHP((。

echo "<script type='text/javascript'>";
echo "function addCommentJS()";
echo "{";
    echo 'document.write("', addCommentPHP() ,'");';
echo "}";
echo "</script>";

步骤 3

在 PHP 函数 addCommentPHP(( 中,查询数据库后,应生成 JavaScript 代码以刷新父窗口并关闭弹出窗口。这就是出现问题的地方。

// Attempt 1
function addCommentPHP() 
{
    // Query the database etc. 
    echo "<script type='text/javascript'>"; 
        echo "opener.location.reload();"; 
        echo "window.close();"; 
    echo "</script>"; 
}

在测试第一次尝试时,我看到一个我意想不到的");}输出到屏幕。当我使用 F12 查看源代码时,我看到它已生成 -

<script type="text/javascript">
    function addCommentJS()
    {
       document.write("
            <script type='text/javascript'> 
                opener.location.reload();
                window.close();
</script>");}

好的,所以,非常明显的错误原因。它正在点击结束</script>标记并关闭在 AddCommentJS(( 中打开的第一个<script>标记。


我决定通过剥离标签来尝试这次它会产生什么。

// Attempt 2 
function addCommentPHP() 
{
    echo "opener.location.reload();";
    echo "window.close();";
}

这会将opener.location.reload()window.close()直接输出到窗口中,检查代码显示 -

<script type="text/javascript">
    function addComment()
    {
        document.write("
            opener.location.reload();
            window.close();
        ");
    }
</script>

最后,我尝试关闭第一个<script>标签,打开另一个集合并将我的代码包含在其中,然后打开另一个<script>标签。(显然,这预计会失败,并且主要是查看将生成哪些代码的实验。

    // Attempt 3
function addComment() 
{
    echo "</script>";
    echo "<script type='text/javascript'>";
        echo "opener.location.reload();";
        echo "window.close();";
    echo "</script>";
    echo "<script>";
}

这将刷新父窗口并立即关闭弹出窗口(如预期的那样(。由此生成的代码是 -

<script type="text/javascript">
    function addCommentJS()
    {
        document.write("
</script>
<script type="text/javascript">
    opener.location.reload();
    window.close(); 
</script>
<script>
    ");}
</script>

有没有办法防止此问题发生?


编辑:

以前我把所有东西(所有的JavaScript(都放在addCommentJS()

function addCommentJS() 
{
    document.write("', addComment() ,'");';
    opener.location.reload();
    window.close();
}

但是,我担心这会异步运行并导致窗口在运行查询之前关闭。

您正在尝试为此处的document.write()调用创建一个JavaScript字符串文字:

echo 'document.write("', addCommentPHP() ,'");';

问题是它没有正确转义,即尖括号<和>仍然具有其 HTML 含义(因此</script>关闭脚本块(。尝试使用 json_encode() 进行转义,它会自动从本机 PHP 值(在本例中为包含另一个脚本块的字符串(创建有效的 JavaScript 文本:

echo 'document.write('.json_encode(addCommentPHP()).');';

您可以转义内部脚本标记,如下所示:

function addCommentPHP() 
{
    // Query the database etc. 
    echo ''x3Cscript type=''text/javascript''>'; 
        echo "opener.location.reload();"; 
        echo "window.close();"; 
    echo ''x3C/script>'; 
}

它的输出需要用单引号括起来。

echo 'document.write(''', addCommentPHP() ,''');';