ignore prefetch and preload script links

related to:
1. https://github.com/rrweb-io/rrweb/issues/52
2. https://github.com/rrweb-io/rrweb/issues/297
3. https://github.com/rrweb-io/rrweb/issues/597
This commit is contained in:
Yanzhen Yu
2026-04-01 12:00:00 +08:00
parent 3c7aeb3b13
commit ec8473b5e4
4 changed files with 51 additions and 7 deletions

View File

@@ -58,8 +58,8 @@ function getTagName(n: elementNode): string {
}
// based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
function escapeRegExp(string: string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
function escapeRegExp(str: string) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
const HOVER_SELECTOR = /([^\\]):hover/;
@@ -84,7 +84,9 @@ export function addHoverClass(cssText: string): string {
}
});
if (selectors.length === 0) return cssText;
if (selectors.length === 0) {
return cssText;
}
const selectorMatcher = new RegExp(
selectors
@@ -170,12 +172,25 @@ function buildNode(
} else if (
tagName === 'meta' &&
n.attributes['http-equiv'] === 'Content-Security-Policy' &&
name == 'content'
name === 'content'
) {
// If CSP contains style-src and inline-style is disabled, there will be an error "Refused to apply inline style because it violates the following Content Security Policy directive: style-src '*'".
// And the function insertStyleRules in rrweb replayer will throw an error "Uncaught TypeError: Cannot read property 'insertRule' of null".
node.setAttribute('csp-content', value);
continue;
} else if (
tagName === 'link' &&
n.attributes.rel === 'preload' &&
n.attributes.as === 'script'
) {
// ignore
} else if (
tagName === 'link' &&
n.attributes.rel === 'prefetch' &&
typeof n.attributes.href === 'string' &&
n.attributes.href.endsWith('.js')
) {
// ignore
} else {
node.setAttribute(name, value);
}

View File

@@ -369,8 +369,8 @@ function serializeNode(
} = options;
// Only record root id when document object is not the base document
let rootId: number | undefined;
if ((doc as unknown as INode).__sn) {
const docId = (doc as unknown as INode).__sn.id;
if (((doc as unknown) as INode).__sn) {
const docId = ((doc as unknown) as INode).__sn.id;
rootId = docId === 1 ? undefined : docId;
}
switch (n.nodeType) {
@@ -568,10 +568,17 @@ function slimDOMExcluded(
} else if (sn.type === NodeType.Element) {
if (
slimDOMOptions.script &&
// script tag
(sn.tagName === 'script' ||
// preload link
(sn.tagName === 'link' &&
sn.attributes.rel === 'preload' &&
sn.attributes.as === 'script'))
sn.attributes.as === 'script') ||
// prefetch link
(sn.tagName === 'link' &&
sn.attributes.rel === 'prefetch' &&
typeof sn.attributes.href === 'string' &&
sn.attributes.href.endsWith('.js')))
) {
return true;
} else if (

View File

@@ -226,6 +226,17 @@ exports[`[html file]: picture.html 1`] = `
</body></html>"
`;
exports[`[html file]: preload.html 1`] = `
"<!DOCTYPE html><html xmlns=\\"http://www.w3.org/1999/xhtml\\" lang=\\"en\\"><head>
<meta charset=\\"UTF-8\\" />
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1.0\\" />
<title>Document</title>
<link />
<link />
</head>
<body></body></html>"
`;
exports[`[html file]: shadow-dom.html 1`] = `
"<!DOCTYPE html><html xmlns=\\"http://www.w3.org/1999/xhtml\\" lang=\\"en\\"><head>
<meta charset=\\"UTF-8\\" />

11
test/html/preload.html Normal file
View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="preload" href="https://example/path/to/preload.js" as="script" />
<link rel="prefetch" href="https://example/path/to/prefetch.js" />
</head>
<body></body>
</html>