未捕获的 DOMException:无法使用 JQuery 设置“innerHTML”属性

Posted

技术标签:

【中文标题】未捕获的 DOMException:无法使用 JQuery 设置“innerHTML”属性【英文标题】:Uncaught DOMException: Failed to set the 'innerHTML' property using JQuery 【发布时间】:2021-06-09 12:31:30 【问题描述】:

我已经搜索了关于此的“类似问题”建议,但找不到匹配项。

代码使用标准 JS 可以正常工作。当我使用 JQuery 重构代码时,问题才出现。我现在收到这个 DOMException 错误。堆栈跟踪指向 responseHandler 函数中的 htmlTableStructure 变量,错误提示标记为无效 XML ,但我找不到任何明显的错误。

代码附在下面。有人可以帮忙吗?

堆栈跟踪

Uncaught DOMException: Failed to set the 'innerhtml' property on 'Element': The provided markup is invalid XML, and therefore cannot be inserted into an XML document.
    at buildFragment (http://localhost:8080/Section5_AjaxJS_war_exploded/resources/js/jquery-3.5.1.js:5032:19)
    at Function.jQuery.parseHTML (http://localhost:8080/Section5_AjaxJS_war_exploded/resources/js/jquery-3.5.1.js:10337:11)
    at new jQuery.fn.init (http://localhost:8080/Section5_AjaxJS_war_exploded/resources/js/jquery-3.5.1.js:3167:33)
    at jQuery (http://localhost:8080/Section5_AjaxJS_war_exploded/resources/js/jquery-3.5.1.js:157:10)
    at responseHandler (http://localhost:8080/Section5_AjaxJS_war_exploded/resources/js/jquery_utils.js:23:30)
    at Object.success (http://localhost:8080/Section5_AjaxJS_war_exploded/resources/js/jquery_utils.js:12:13)
    at fire (http://localhost:8080/Section5_AjaxJS_war_exploded/resources/js/jquery-3.5.1.js:3496:31)
    at Object.fireWith [as resolveWith] (http://localhost:8080/Section5_AjaxJS_war_exploded/resources/js/jquery-3.5.1.js:3626:7)
    at done (http://localhost:8080/Section5_AjaxJS_war_exploded/resources/js/jquery-3.5.1.js:9786:14)
    at XMLHttpRequest.<anonymous> (http://localhost:8080/Section5_AjaxJS_war_exploded/resources/js/jquery-3.5.1.js:10047:9)

网络表单

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
        PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>Film Search</title>
    <script
            src="resources/js/jquery_utils.js"
            type="text/javascript"></script>
    <script src="resources/js/jquery-3.5.1.js"
            type="text/javascript"></script>

</head>
<body>
    <table border="1" bgcolor="#20b2aa">
        <tr><th><big></big>Film Search Application</th></tr>
    </table>
<p/>
    <fieldset>
        <legend>Retrieve Data from GetAllFilms</legend>
        <form action="#">
            <input type="button" value="XML" onclick="getAllFilms('GetAllFilms', 'xml')"/>
            <input type="button" value="JSON" onclick="getAllFilms('GetAllFilms', 'json')"/>
            <input type="button" value="TEXT" onclick="getAllFilms('GetAllFilms', 'text')"/>
        </form>
        <p/>
        <div id="getallfilms"></div>
    </fieldset><br></br>
</body>
</html>

Javascript Onclick 功能

function getAllFilms(servletAddress, dataFormat) 
    $.ajax(

        url: servletAddress,                                
        type: "POST",                                       
        dataType : dataFormat,                              
        data : format : dataFormat,                       

        success: function(servletResponse)                 
            responseHandler(servletResponse, dataFormat);   
        
    );

Javascript 响应处理函数

function responseHandler(servletResponse, dataFormat) 

    // create base table structure object, with headings
    let htmlTableStructure = $(
        "<table border='1' class='ajaxTable'>" +
        "<tr>" +
            "<th>Film Id</th>" +
            "<th>Name</th>" +
            "<th>Year</th>" +
            "<th>Director</th>" +
            "<th>Cast</th>" +
            "<th>Plot</th>" +
        "</tr>"
    );

    // if data format passed in is json
    if (dataFormat === "json") 

        // append rows to html table structure
        $.each(servletResponse.films, function(i, filmObject) 
            htmlTableStructure.append("<tr>");
            $.each(filmObject, function(key, value)
                htmlTableStructure.append("<td>" + value + "</td>")
            )
            htmlTableStructure.append("</tr>");
        );

    // if data format passed in is xml
     else if (dataFormat === "xml") 

        // append rows to html table structure
        // loop through each film node in xml & get child node values
        $(servletResponse).find('film').each(function () 
            htmlTableStructure.append("" +
                "<tr>" +
                    "<td>" + $(this).find('id').text() + "</td>" +
                    "<td>" + $(this).find('title').text() + "</td>" +
                    "<td>" + $(this).find('year').text() + "</td>" +
                    "<td>" + $(this).find('director').text() + "</td>" +
                    "<td>" + $(this).find('stars').text() + "</td>" +
                    "<td>" + $(this).find('review').text() + "</td>" +
                "</tr>"
            );
        );

    // if data format passed in is text
     else 

        // append rows to html table structure

        // split servlet response into rows using $ delimiter (rows 3 & 10)
        // ignore first row (this is the header, which we've already hardcoded)
        let rowString = servletResponse.split("$").slice(1);

        // then for each remaining row, split into fields by # delimiter and wrap row in <tr>
        $.each(rowString, function (i, stringLine) 
            htmlTableStructure.append(
                    "<tr>" +
                        "<td>" + stringLine.split('#') + "</td>" +
                    "</tr>"
            );
        )

     $("#getallfilms").append(htmlTableStructure + "</table>");

【问题讨论】:

您将htmlTableStructure 视为字符串。与其使用htmlTableStructure = $("&lt;table&gt;"); htmlTableStructure .append("&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;"),不如将​​其保留为字符串:htmlTableStructure = "&lt;table&gt;"; htmlTableStructure += "&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;"; htmlTableStructure += "&lt;/table&gt;"; $("#getall").append(htmlTableStructure); - 但是你有责任将结束标签放在正确的位置 - 所以构建节点并附加到它们通常更安全 - 只是不要将它们视为字符串。 【参考方案1】:

您正在尝试将内容附加到无效标记。您首先创建一个&lt;table&gt;,但不要关闭它。 jQuery 中的 .append(...) 方法将内容附加到 DOM 节点的末尾。

.append(htmlTableStructure + "&lt;/table&gt;");这种东西是不对的。

您需要继续重构代码以使其兼容。回顾一下 jQuery 的 append 方法是如何工作的可能是个好主意:https://api.jquery.com/append/

例如:

htmlTableStructure = $("<table></table>");
htmlTableStructure.append("<tr><th>...</th>...</tr>");
htmlTableStructure.append("<tr><td>...</td>...</tr>");

【讨论】:

感谢您的回复。我想我有点误解 .append 的工作原理。它现在可以按照@freedomn-m 方法工作。但我想那不再使用 append。

以上是关于未捕获的 DOMException:无法使用 JQuery 设置“innerHTML”属性的主要内容,如果未能解决你的问题,请参考以下文章

未捕获的 DOMException:无法在“范围”上执行“setStart”:偏移量大于节点的长度

未捕获的 DOMException:无法在“IDBObjectStore”上执行“删除”:事务未处于活动状态

未捕获的 DOMException:无法在“CustomElementRegistry”上执行“定义”:此名称已用于此注册表

“未捕获(承诺)的DOMException:无法为范围注册ServiceWorker”-脚本资源位于重定向后面,不允许使用

iframe chrome:未捕获的 DOMException:无法从“Window”读取“localStorage”属性:此文档的访问被拒绝

如何处理未捕获(承诺)DOMException:播放()请求被暂停()调用中断