当前位置: 首页 > 知识库问答 >
问题:

检查HTML代码段是否对JavaScript有效

公孙宸
2023-03-14

我需要一个可靠的JavaScript库/函数来检查超文本标记语言片段是否有效,我可以从我的代码中调用。例如,它应该检查打开的标签和引号是否关闭,嵌套是否正确等。

我不希望验证失败,因为有些东西不是100%标准的(但无论如何都会工作)。

共有3个答案

窦夜洛
2023-03-14

到目前为止,没有一个解决方案能很好地回答最初的问题,尤其是在涉及到

我不希望验证失败,因为有些东西不是百分之百的标准(但无论如何都会有效)。

太长,读不下去了

所以我使用了关于这个主题的答案和评论的输入,并创建了一个执行以下操作的方法:

  • 如果有效,逐个标记检查html字符串标记
  • 尝试呈现html字符串
  • 将理论上要创建的标记计数与实际渲染的html dom标记计数进行比较
  • 如果选中“严格”,<代码>

退换商品

  • 如果呈现的html与给定的html字符串相同,则为true
  • 如果其中一个检查失败,则为false
  • 如果呈现的html看起来有效但不等于给定的html字符串,则规范化html字符串

规范化意味着,在渲染时,浏览器有时会忽略或修复输入的特定部分(例如为<代码>

大多数时候,规范化只会返回对原始html字符串稍加修改的版本,但有时结果会大相径庭。因此,在将用户输入保存到db或盲目渲染之前,应使用此选项标记用户输入以供进一步审查。(有关规范化的示例,请参见JSFIDLE)

检查会考虑以下例外情况

  • 忽略单引号到双引号的规范化
  • 在渲染过程中,图像和其他带有src属性的标记将被“解除防护”
  • (如果不严格)忽略<代码>

.

function simpleValidateHtmlStr(htmlStr, strictBoolean) {
  if (typeof htmlStr !== "string")
    return false;

  var validateHtmlTag = new RegExp("<[a-z]+(\s+|\"[^\"]*\"\s?|'[^']*'\s?|[^'\">])*>", "igm"),
    sdom = document.createElement('div'),
    noSrcNoAmpHtmlStr = htmlStr
      .replace(/ src=/, " svhs___src=") // disarm src attributes
      .replace(/&amp;/igm, "#svhs#amp##"), // 'save' encoded ampersands
    noSrcNoAmpIgnoreScriptContentHtmlStr = noSrcNoAmpHtmlStr
      .replace(/\n\r?/igm, "#svhs#nl##") // temporarily remove line breaks
      .replace(/(<script[^>]*>)(.*?)(<\/script>)/igm, "$1$3") // ignore script contents
      .replace(/#svhs#nl##/igm, "\n\r"),  // re-add line breaks
    htmlTags = noSrcNoAmpIgnoreScriptContentHtmlStr.match(/<[a-z]+[^>]*>/igm), // get all start-tags
    htmlTagsCount = htmlTags ? htmlTags.length : 0,
    tagsAreValid, resHtmlStr;


  if(!strictBoolean){
    // ignore <br/> conversions
    noSrcNoAmpHtmlStr = noSrcNoAmpHtmlStr.replace(/<br\s*\/>/, "<br>")
  }

  if (htmlTagsCount) {
    tagsAreValid = htmlTags.reduce(function(isValid, tagStr) {
      return isValid && tagStr.match(validateHtmlTag);
    }, true);

    if (!tagsAreValid) {
      return false;
    }
  }


  try {
    sdom.innerHTML = noSrcNoAmpHtmlStr;
  } catch (err) {
    return false;
  }

  // compare rendered tag-count with expected tag-count
  if (sdom.querySelectorAll("*").length !== htmlTagsCount) {
    return false;
  }

  resHtmlStr = sdom.innerHTML.replace(/&amp;/igm, "&"); // undo '&' encoding

  if(!strictBoolean){
    // ignore empty attribute normalizations
    resHtmlStr = resHtmlStr.replace(/=""/, "")
  }

  // compare html strings while ignoring case, quote-changes, trailing spaces
  var
    simpleIn = noSrcNoAmpHtmlStr.replace(/["']/igm, "").replace(/\s+/igm, " ").toLowerCase().trim(),
    simpleOut = resHtmlStr.replace(/["']/igm, "").replace(/\s+/igm, " ").toLowerCase().trim();
  if (simpleIn === simpleOut)
    return true;

  return resHtmlStr.replace(/ svhs___src=/igm, " src=").replace(/#svhs#amp##/, "&amp;");
}

在这里,您可以在JSFiddlehttps://jsfiddle.net/abernh/twgj8bev/中找到它,以及不同的测试用例,包括

"<a href='blue.html id='green'>missing attribute quotes</a>" // FAIL
"<a>hell<B>o</B></a>"                                        // PASS
'<a href="test.html">hell<b>o</b></a>'                       // PASS
'<a href=test.html>hell<b>o</b></a>',                        // PASS
"<a href='test.html'>hell<b>o</b></a>",                      // PASS
'<ul><li>hell</li><li>hell</li></ul>',                       // PASS
'<ul><li>hell<li>hell</ul>',                                 // PASS
'<div ng-if="true && valid">ampersands in attributes</div>'  // PASS

.

冯飞鹏
2023-03-14

好吧,这段代码:

function tidy(html) {
    var d = document.createElement('div');
    d.innerHTML = html;
    return d.innerHTML;
}

这将尽浏览器的最大能力“纠正”格式错误的HTML。如果这对您有帮助,那么这比尝试验证HTML要容易得多。

薛经纶
2023-03-14

更新:此答案有限-请参阅下面的编辑。

扩展@kolink的答案,我使用:

var checkHTML = function(html) {
  var doc = document.createElement('div');
  doc.innerHTML = html;
  return ( doc.innerHTML === html );
}

也就是说,我们使用超文本标记语言创建一个临时div。为了做到这一点,浏览器将根据超文本标记语言字符串创建一个DOM树,这可能涉及关闭标签等。

将div的HTML内容与原始HTML进行比较将告诉我们浏览器是否需要更改任何内容。

checkHTML('<a>hell<b>o</b>')

返回false。

checkHTML('<a>hell<b>o</b></a>')

返回true。

编辑:正如@Quentin在下面指出的那样,由于各种原因,这一点过于严格:浏览器通常会修复省略的结束标记,即使结束标记对于该标记是可选的。如:

<p>one para
<p>second para

...被认为是有效的(因为Ps可以省略结束标记),但checkHTML将返回false。浏览器还将规范化标记大小写,并更改空白。在决定使用此方法时,您应该了解这些限制。

 类似资料:
  • 问题内容: 我有一个安排计时器的游戏。我有这个CoresManager文件: 我在游戏中使用这个: 如果播放器注销并且服务器重新启动,CoresManager计时器将停止运行。为了使其再次运行,我添加了代码以使其在您再次登录后再次执行startTimer()。但是,由于如果服务器未注销,计时器仍在运行,因此计时器开始运行两次。根据您注销和登录的次数,计时器开始减去2或更多。我认为,如果有代码确定计

  • 我正在将带有用户信息的对象从客户端发送到我的服务器: 我害怕一个“坏用户”,试图黑我的系统修改客户端,就像这样: 然后,如果我在服务器中得到这个对象,并更新数据库,用户就会很有名,而且是溢价的。 在服务器端,我只需要字段“name”、“username”、“gender”和“avatar”。 如果对象“NewUserData”有其他意外的字段,我如何签入node.js? 注意:我正在寻找一个通用的

  • 问题内容: 如何检查值是否是JavaScript中的Object? 问题答案: 更新 : 这个答案是不完整的,并且会产生误导性的结果 。例如,在JavaScript中也被视为类型,更不用说其他几种极端情况了。请遵循以下建议,然后转到其他 原始答案 : 尝试使用和/或。 编辑:这个答案给出了一个如何检查变量属性的想法,但是它不是一个防弹配方(毕竟根本没有配方!)来检查它是否是一个对象,而不是对象。由

  • 在查看几个不同的文档时,我只看到地图(ECMAScript6)键是布尔值、字符串或整数。有没有一种方法可以使用另一个定制的对象(用新的CustomObject(x, y)构造函数调用调用)作为键添加? 我可以添加一个对象作为密钥,但无法检查地图是否有所述对象。 有办法解决这个问题吗? https://developer.mozilla.org/en-US/docs/Web/JavaScript/R

  • 这里有几个关于如何检查对象中是否存在属性的答案。 我一直在使用 但我想知道这和

  • 本文向大家介绍JavaScript / Typescript对象是否为空检查?,包括了JavaScript / Typescript对象是否为空检查?的使用技巧和注意事项,需要的朋友参考一下 对于null检查,可以使用!健康)状况。 示例 以下是代码- 要运行以上程序,您需要使用以下命令- 在这里,我的文件名为demo305.js。 输出结果 这将产生以下输出-