首页 > 解决方案 > 升级到 JQuery 3.5.1 后字段中断

问题描述

我有一个基于列表中的内容使用 javascript 创建的表。这在 Jquery 3.4 中运行良好,但是当我升级到 3.5 时,我看到了这个中断。

HTML

    <h5>Questions</h5>
    <table id="questionTable" class="table q">
        <thead>
        </thead>
        <tbody id="qTable"></tbody>
    </table>
    
    <div id="questionDiv">
        <input type="button" value="Add Question" onclick="AddNewQuestion()" class="btn btn-primary"/>
    </div>
    
    <hr />

<div id="questionDiv">
    <input type="submit" value="Submit" class="btn btn-primary" />
</div>

Javascript

 <script type="text/javascript">
    
            $(document).ready(function () {
                $(function () {
                    AddCurrentQuestions();
                });
            });
    
            var table = document.getElementById("qTable");
            var rowCount = table.rows.length;
            var counter = rowCount.length;
    
            function AddCurrentQuestions() {
    
                var status = @Html.Raw(Json.Encode(Model.isNull));
    
                if (status == false) {
    
                    @{ Model.QuestionList.Add(new Performance_Planning.ViewModel.QuestionViewModel.Questions());}
                    var questionItems = JSON.parse('@Html.Raw(Json.Encode(@Model.QuestionList))');
    
                    for (var i = 0; i < questionItems.length - 1; i++) {
                        var qItem = questionItems[i];
                        var questionDetail = qItem.Question;
    
                        //Create fields
                        var qTextCell = "<td><textarea id='QuestionList_" + i + "_Question' name='QuestionList[" + i + "].Question' class='Questions' /></td>";
                        var indexCell = "<td style='display:none'> <input name='QuestionList.Index' type='hidden' value='" + i + "' /></td>";
                        var removeCell = "<td align='center'><input id='btnDelLine'" + i + "type='button' value='Remove' onclick=\"removeRow('" + i + "')\" class='btn btn-primary' /></td>";
    
                        var newRow = "<tr id='qLineItem" + i + "'>" + indexCell + qTextCell + removeCell + "</tr>";
    
                        //Add row to table
                        $('#qTable').append(newRow);
    
                        //Add Values
                        $('#QuestionList_' + i + "_Question").val(questionDetail)
    
    
                        counter = i;
                    };
                } else {
                    counter = 0;
                    AddNewQuestion();
                }
            };
    
            function AddNewQuestion() {
                @{ Model.QuestionList.Add(new Performance_Planning.ViewModel.QuestionViewModel.Questions());}
    
                counter++;
    
                //Create field
                var indexCell = "<td style='display:none'> <input name='QuestionList.Index' type='hidden' value='" + counter + "' /></td>";
                var qTextCell = "<td><textarea id='QuestionList_" + counter + "_Question' name='QuestionList[" + counter + "].Question' class='Questions' /></td>";
                var removeCell = "<td align='center'><input id='btnDelLine'" + counter + "type='button' value='Remove' onclick=\"removeRow('" + counter + "')\" class='btn btn-primary' /></td>";
    
                var newRow = "<tr id='qLineItem" + counter + "'>" + indexCell + qTextCell + removeCell + "</tr>";
    
                $('#qTable').append(newRow);
            };
    
            function removeRow(id) {
                var rowId = "qLineItem" + id;
                var row = document.getElementById(rowId);
                row.parentNode.removeChild(row);
            };
    
        </script>
        
        } 

我最终看到的是删除按钮在 3.5.1 中被视为文本,但在 3.4 中不会出现这种情况。我不确定如何解决这个问题,或者我是否需要找出另一种方法来编写这个页面。

当我查看网页并检查该字段时,我看到它执行以下操作:

<textarea id="QuestionList_0_Question" name="QuestionList[0].Question" class="Questions">
  "</td><td align='center'><input id='btnDelLine'0type='button' value='Remove' onclick="removeRow('0')" class='btn btn-primary' /></td></tr></tbody></table>"

标签: javascripthtml

解决方案


textarea元素应该有一个单独的关闭标签。不允许自行关闭。所以这不是有效的 HTML:

<textarea />

但这是:

<textarea></textarea>

显然,jQuery 3.5 在这方面更加严格。对3.5 变更日志的检查表明,这是他们应用的安全修复的结果:

此版本的主要更改是安全修复,您可能需要更改自己的代码以适应。原因如下:jQuery 在其jQuery.htmlPrefilter方法中使用了正则表达式,以确保所有结束标记在传递给方法时都符合 XHTML。例如,此预过滤器确保调用 likejQuery("<div class='hot' />")实际转换为jQuery("<div class='hot'></div>").最近,报告了一个问题,表明正则表达式可能引入跨站点脚本 (XSS) 漏洞。

jQuery <= 3.4.1 中的 HTML 解析器通常会做正确的事情,但在某些极端情况下,解析会产生意想不到的后果。jQuery 团队同意有必要在次要版本中修复此问题,即使某些代码依赖于以前的行为并且可能会中断。该jQuery.htmlPrefilter函数在 3.5.0 中不使用正则表达式,而是通过原样传递字符串。

可以看到在 3.5 之前,jQuery 会如何实时更改,<textarea />从而<textarea></textarea>修复您所犯的错误。但是现在 jQuery 3.5 版不再这样做了,因此您的 HTML 仍然无效,从而导致意外呈现,之后的所有<textarea />内容都作为该文本区域元素的内容结束。


推荐阅读