fix: scanner ignoriert metadaten-links (gmpg.org rel=profile); version 1.2.0

- Nur ladende <link rel=...> (stylesheet/preload/icon/...) werden gezaehlt;
  rel=profile/canonical/pingback etc. (z.B. gmpg.org) sind keine Requests mehr.
- Plugin-Version + Header auf 1.2.0 (passend zu readme), Changelog-Eintrag.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
s4luorth
2026-06-07 16:57:09 +02:00
parent b03f18a794
commit de4f16fefa
4 changed files with 33 additions and 6 deletions

View File

@@ -13,6 +13,16 @@ function normHost(h) {
return String(h || '').toLowerCase().replace(/:.*$/, '').replace(/^www\./, '');
}
// Only these <link rel="…"> values actually fetch/connect to a resource.
// Everything else (profile, canonical, alternate, pingback, EditURI, wlwmanifest,
// shortlink, https://api.w.org/, …) is pure metadata and triggers no request —
// e.g. gmpg.org via rel="profile" must NOT be reported.
const LINK_LOADING_RELS = new Set([
'stylesheet', 'preload', 'modulepreload', 'preconnect', 'dns-prefetch',
'prefetch', 'prerender', 'icon', 'shortcut icon', 'apple-touch-icon',
'apple-touch-icon-precomposed', 'mask-icon', 'manifest', 'fetch',
]);
/** Extract absolute resource URLs (with a type tag) from one HTML document. */
export function extractResources(html, baseUrl) {
const out = [];
@@ -23,9 +33,16 @@ export function extractResources(html, baseUrl) {
const body = m[2];
let raw = '';
if (tag === 'object') raw = attr(body, 'data');
else if (tag === 'link') raw = attr(body, 'href');
else raw = attr(body, 'src');
if (tag === 'object') {
raw = attr(body, 'data');
} else if (tag === 'link') {
// Skip metadata links that never load anything (rel="profile" etc.).
const rel = attr(body, 'rel').toLowerCase().trim();
if (!LINK_LOADING_RELS.has(rel)) continue;
raw = attr(body, 'href');
} else {
raw = attr(body, 'src');
}
if (!raw) continue;
if (/^(data:|blob:|javascript:|mailto:|tel:|#|about:)/i.test(raw)) continue;

View File

@@ -8,6 +8,8 @@ const ok = (name, cond, extra = '') => {
const html = `
<!DOCTYPE html><html><head>
<link rel="profile" href="https://gmpg.org/xfn/11">
<link rel="canonical" href="https://other.example/x">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<script src="/wp-includes/js/jquery.js"></script>
<script src="https://www.googletagmanager.com/gtag/js?id=G-XYZ"></script>
@@ -31,6 +33,8 @@ ok('finds external script (gtm)', resources.some((r) => r.type === 'script' && r
ok('resolves relative script to absolute', resources.some((r) => r.url === 'https://example.com/wp-includes/js/jquery.js'));
ok('finds external img', resources.some((r) => r.type === 'img' && r.url.includes('cdn.example.com')));
ok('finds link stylesheet', resources.some((r) => r.type === 'link' && r.url.includes('fonts.googleapis.com')));
ok('ignores rel=profile (gmpg.org)', !resources.some((r) => r.url.includes('gmpg.org')));
ok('ignores rel=canonical', !resources.some((r) => r.url.includes('other.example')));
ok('finds object data (vimeo)', resources.some((r) => r.type === 'object' && r.url.includes('player.vimeo.com')));
ok('ignores anchor href', !resources.some((r) => r.url.includes('twitter.com')));