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:
@@ -58,8 +58,8 @@ function getTagName(n: elementNode): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
|
// based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
|
||||||
function escapeRegExp(string: string) {
|
function escapeRegExp(str: string) {
|
||||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
||||||
}
|
}
|
||||||
|
|
||||||
const HOVER_SELECTOR = /([^\\]):hover/;
|
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(
|
const selectorMatcher = new RegExp(
|
||||||
selectors
|
selectors
|
||||||
@@ -170,12 +172,25 @@ function buildNode(
|
|||||||
} else if (
|
} else if (
|
||||||
tagName === 'meta' &&
|
tagName === 'meta' &&
|
||||||
n.attributes['http-equiv'] === 'Content-Security-Policy' &&
|
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 '*'".
|
// 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".
|
// And the function insertStyleRules in rrweb replayer will throw an error "Uncaught TypeError: Cannot read property 'insertRule' of null".
|
||||||
node.setAttribute('csp-content', value);
|
node.setAttribute('csp-content', value);
|
||||||
continue;
|
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 {
|
} else {
|
||||||
node.setAttribute(name, value);
|
node.setAttribute(name, value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -369,8 +369,8 @@ function serializeNode(
|
|||||||
} = options;
|
} = options;
|
||||||
// Only record root id when document object is not the base document
|
// Only record root id when document object is not the base document
|
||||||
let rootId: number | undefined;
|
let rootId: number | undefined;
|
||||||
if ((doc as unknown as INode).__sn) {
|
if (((doc as unknown) as INode).__sn) {
|
||||||
const docId = (doc as unknown as INode).__sn.id;
|
const docId = ((doc as unknown) as INode).__sn.id;
|
||||||
rootId = docId === 1 ? undefined : docId;
|
rootId = docId === 1 ? undefined : docId;
|
||||||
}
|
}
|
||||||
switch (n.nodeType) {
|
switch (n.nodeType) {
|
||||||
@@ -568,10 +568,17 @@ function slimDOMExcluded(
|
|||||||
} else if (sn.type === NodeType.Element) {
|
} else if (sn.type === NodeType.Element) {
|
||||||
if (
|
if (
|
||||||
slimDOMOptions.script &&
|
slimDOMOptions.script &&
|
||||||
|
// script tag
|
||||||
(sn.tagName === 'script' ||
|
(sn.tagName === 'script' ||
|
||||||
|
// preload link
|
||||||
(sn.tagName === 'link' &&
|
(sn.tagName === 'link' &&
|
||||||
sn.attributes.rel === 'preload' &&
|
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;
|
return true;
|
||||||
} else if (
|
} else if (
|
||||||
|
|||||||
@@ -226,6 +226,17 @@ exports[`[html file]: picture.html 1`] = `
|
|||||||
</body></html>"
|
</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`] = `
|
exports[`[html file]: shadow-dom.html 1`] = `
|
||||||
"<!DOCTYPE html><html xmlns=\\"http://www.w3.org/1999/xhtml\\" lang=\\"en\\"><head>
|
"<!DOCTYPE html><html xmlns=\\"http://www.w3.org/1999/xhtml\\" lang=\\"en\\"><head>
|
||||||
<meta charset=\\"UTF-8\\" />
|
<meta charset=\\"UTF-8\\" />
|
||||||
|
|||||||
11
test/html/preload.html
Normal file
11
test/html/preload.html
Normal 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>
|
||||||
Reference in New Issue
Block a user