jQuery Core 3.5 升级指南


link jQuery.htmlPrefilter 的变化

link 权宜之计(工作方案)

如果你想升级到 jQuery 3.5.0 或更高版本,但目前没有时间处理破坏性变更,并且你正在使用 jQuery Migrate 3.4.0 或更高版本,你可以通过调用以下方法来恢复到以前的行为:

1
jQuery.migrateEnablePatches( "self-closed-tags" );

只要调用了这个方法,jQuery Migrate 3.4.0 或更高版本就会对受此变更影响的所有输入记录警告。注意:如果你手动覆盖了 jQuery.htmlPrefilter,你将失去这些警告!

如果你没有使用 jQuery Migrate,不要仅仅为了这一个权宜之计而添加它。相反,你可以在加载 jQuery 后通过重新定义 jQuery.htmlPrefilter 来恢复之前的行为:

1
2
3
4
var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi;
jQuery.htmlPrefilter = function( html ) {
return html.replace( rxhtmlTag, "<$1></$2>" );
};

请注意,如果你这样做,你将失去 jQuery 3.5.0 的安全修复,并且你必须更加小心传递给 jQuery 操作方法的 HTML;常规的 HTML 清洗(sanitizing)是不够的。一些安全库针对 jQuery 有专门的清洗设置。例如,DOMPurify2.0.17 或更早版本中曾支持 SAFE_FOR_JQUERY 标志。

1
2
var sanitizedHtml = DOMPurify.sanitize( unsafeHtml, { SAFE_FOR_JQUERY: true } );
elem.html( sanitizedHtml );

link 变更说明

jQuery.htmlPrefilter 用于修改和过滤通过 jQuery 操作方法传递的 HTML 字符串。在 3.5.0 之前的 jQuery 版本中,该函数的默认值会将类似 XHTML 的标签替换为在 HTML 中可运行的版本。例如,以前的以下内容:

1
jQuery( "<div/><span/>" );

会创建如下结构:

1
2
<div></div>
<span></span>

因为 <div/> 被替换为 <div></div>,而 <span/> 被替换为 <span></span>

在 jQuery 3.5.0 中,jQuery.htmlPrefilter 方法始终原样返回其参数。现代浏览器通常以 HTML 模式解析和渲染 HTML 字符串。诸如 <p><span> 之类的元素在 HTML 中永远不是自闭合的,因此浏览器会将 <p/><span/> 这样的字符串解释为 <p><span> 并保持标签开启。浏览器会在字符串末尾或在不能包含在该元素中的元素处关闭标签,因此另一个 <p> 标签会关闭现有的已开启 <p> 标签。

1
2
3
<div>
<span></span>
</div>

为了避免这种情况,对于可能有内容的标签,请不要使用自闭合标签,除非你的页面运行在 XHTML 模式下。请确保你发送了正确的 mime 类型:application/xhtml+xml;否则,你的页面实际上将以 HTML 模式运行。

如果你正在编写一个库,并且希望它在 HTML 和 XHTML 模式下都能工作,请记住对空元素(即在 HTML 中没有闭合标签的元素)使用自闭合标签。例如,不要使用:

1
jQuery( "<div/><img/>" );

而要这样做:

1
jQuery( "<div></div><img/>" );

在 jQuery 3.5.0 或更高版本中仍然有效的一种常用输入是带有或不带有属性的单个标签:

1
jQuery( "<div class='yellow' />" );

这是因为它是符合 XHTML 规范的,并且在 HTML 中,解析器首先将其更改为仅开启标签:<div class='yellow'>,但随后在到达输入末尾时立即自动关闭它。