{"id":15725,"date":"2026-09-06T11:09:51","date_gmt":"2026-09-06T09:09:51","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/werkzeuge\/wordpress-rest-route-inventory\/"},"modified":"2026-09-06T11:09:51","modified_gmt":"2026-09-06T09:09:51","slug":"wordpress-rest-route-inventory","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wordpress-rest-route-inventory\/","title":{"rendered":"WordPress-REST-Routeninventar: was eine Seite ohne Anmeldung herausgibt"},"content":{"rendered":"<div class=\"gtm-analyser-container\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<p style=\"color: var(--text-secondary, #a0a0b0); margin-bottom: 20px;\">Das Verzeichnis unter \/wp-json\/ f\u00fchrt jede angemeldete Route auf, auch die jedes Erweiterungsmoduls. \u00dcber Rechte sagt es nichts: Die Pr\u00fcfung steckt in der Route und l\u00e4uft erst beim Aufruf. Dieses Werkzeug macht deshalb beides \u2014 es liest das Verzeichnis und ruft danach zehn bekannte Routen ohne Anmeldedaten ab.<\/p>\n<div style=\"margin-bottom: 14px;\">\n        <label for=\"rs-url\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Adresse der WordPress-Installation<\/label><br \/>\n        <input id=\"rs-url\" type=\"text\" value=\"https:\/\/wordpress.org\/news\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; box-sizing: border-box; font-family: monospace;\"><\/p>\n<p style=\"color: var(--text-secondary, #a0a0b0); font-size: 0.78rem; margin: 5px 0 0;\">Die Adresse, unter der die Seite l\u00e4uft, samt Unterverzeichnis wie \/blog, falls vorhanden.<\/p>\n<\/p><\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); font-size: 0.82rem; margin-bottom: 16px;\">Von diesem Server gehen elf lesende Anfragen hinaus: das Verzeichnis und zehn bekannte Routen. Geschrieben wird nichts, angemeldet wird sich nicht. Gespeichert wird nur die Abfrage selbst, f\u00fcr die Stundengrenze.<\/p>\n<p>    <button id=\"rs-btn\" class=\"button\" style=\"background: var(--accent, #7ee787); color: var(--on-accent, #0b1114); border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Routen lesen<\/button><\/p>\n<div id=\"rs-ausgabe\" style=\"margin-top: 22px;\"><\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); font-size: 0.8rem; margin: 24px 0 0;\">F\u00fcnf Abfragen je Stunde. Nur GET auf Standardadressen, private Adressbereiche werden abgelehnt.<\/p>\n<\/div>\n<p><script>\n(function () {\n    'use strict';<\/p>\n<p>    const T = {\"einleitung\":\"Das Verzeichnis unter \\\/wp-json\\\/ f\u00fchrt jede angemeldete Route auf, auch die jedes Erweiterungsmoduls. \u00dcber Rechte sagt es nichts: Die Pr\u00fcfung steckt in der Route und l\u00e4uft erst beim Aufruf. Dieses Werkzeug macht deshalb beides \u2014 es liest das Verzeichnis und ruft danach zehn bekannte Routen ohne Anmeldedaten ab.\",\"label_url\":\"Adresse der WordPress-Installation\",\"hinweis_url\":\"Die Adresse, unter der die Seite l\u00e4uft, samt Unterverzeichnis wie \\\/blog, falls vorhanden.\",\"datenschutz\":\"Von diesem Server gehen elf lesende Anfragen hinaus: das Verzeichnis und zehn bekannte Routen. Geschrieben wird nichts, angemeldet wird sich nicht. Gespeichert wird nur die Abfrage selbst, f\u00fcr die Stundengrenze.\",\"knopf\":\"Routen lesen\",\"grenze\":\"F\u00fcnf Abfragen je Stunde. Nur GET auf Standardadressen, private Adressbereiche werden abgelehnt.\",\"laeuft\":\"Verzeichnis wird gelesen und die Stichprobenrouten abgerufen \u2026\",\"urteil_gut\":\"Nichts steht im Weg\",\"urteil_warnung\":\"Einen Blick wert\",\"urteil_kritisch\":\"Braucht Aufmerksamkeit\",\"zusammenfassung\":\"{routen} Routen in {raeume} Namensr\u00e4umen, davon nehmen {schreibend} schreibende Methoden an.\",\"kein_verzeichnis_text\":\"Unter dieser Adresse lie\u00df sich kein Routenverzeichnis lesen.\",\"h_proben\":\"Die Stichprobe, ohne Anmeldung abgerufen\",\"proben_hinweis\":\"Offen hei\u00dft, die Route hat mit 200 und Inhalt geantwortet. Gesch\u00fctzt hei\u00dft, die Rechtepr\u00fcfung hat mit 401 oder 403 abgelehnt. Fehlt hei\u00dft 404.\",\"h_raeume\":\"Namensr\u00e4ume\",\"h_seite\":\"Was das Verzeichnis \u00fcber die Seite sagt\",\"h_befunde\":\"Befunde\",\"spalte_route\":\"Route\",\"spalte_zustand\":\"Zustand\",\"spalte_status\":\"Status\",\"spalte_anzahl\":\"Eintr\u00e4ge\",\"spalte_raum\":\"Namensraum\",\"spalte_routen\":\"Routen\",\"zustand_offen\":\"offen\",\"zustand_geschuetzt\":\"gesch\u00fctzt\",\"zustand_fehlt\":\"fehlt\",\"zustand_gesperrt\":\"gesperrt\",\"zustand_fehler\":\"Fehler\",\"zeile_name\":\"Name\",\"zeile_beschreibung\":\"Beschreibung\",\"zeile_sprache\":\"Sprache\",\"zeile_zeitzone\":\"Zeitzone\",\"zeile_anmeldung\":\"Anmeldeverfahren\",\"zeile_weg\":\"Routenform\",\"zeile_dauer\":\"Dauer\",\"zeile_limit\":\"Abfragen in dieser Stunde \u00fcbrig\",\"keine_anmeldung\":\"keines genannt\",\"weg_wp_json\":\"\\\/wp-json\\\/ (sprechende Adressen)\",\"weg_rest_route\":\"?rest_route= (einfache Adressen)\",\"keine_befunde\":\"Keine Befunde.\",\"stufe_hoch\":\"Hoch\",\"stufe_mittel\":\"Mittel\",\"stufe_niedrig\":\"Niedrig\",\"stufe_info\":\"Hinweis\",\"stufe_gut\":\"Gut\",\"befund_kein_verzeichnis\":\"Das Verzeichnis lie\u00df sich nicht abrufen || Der Abruf scheiterte mit: {fehler}.\",\"befund_rest_abgeschaltet\":\"Das Routenverzeichnis antwortet mit 404 || Entweder ist die REST-Schnittstelle abgeschaltet, oder etwas davor sperrt die Adresse.\",\"befund_rest_gesperrt\":\"Das Routenverzeichnis ist gesch\u00fctzt || Status {status}: schon das Lesen des Verzeichnisses verlangt eine Anmeldung.\",\"befund_kein_json\":\"Kein JSON unter der Verzeichnisadresse || Status {status}, Inhaltstyp {typ}. Dort antwortet etwas, aber nicht die REST-Schnittstelle.\",\"befund_json_unlesbar\":\"Das Verzeichnis ist kein lesbares JSON || Die Antwort kam an, lie\u00df sich aber nicht zerlegen.\",\"befund_benutzer_offen\":\"Die Benutzerliste ist offen || \\\/wp\\\/v2\\\/users hat mit {anzahl} Eintr\u00e4gen geantwortet. Namen und Anmeldek\u00fcrzel sind die erste H\u00e4lfte eines Anmeldeversuchs, und diese Route gibt sie ohne jede Anmeldung heraus.\",\"befund_benutzer_zu\":\"Die Benutzerliste ist nicht offen || Status {status}. Entweder ist die Route abgeschaltet, oder die Rechtepr\u00fcfung lehnt ab.\",\"befund_route_offen_settings\":\"Die Einstellungen sind lesbar || {pfad} hat mit 200 geantwortet. Diese Route verlangt in einer Standardinstallation Verwalterrechte.\",\"befund_route_offen_plugins\":\"Die Modulliste ist lesbar || {pfad} hat mit 200 geantwortet. Versionsnummern installierter Module sind der k\u00fcrzeste Weg zu einem passenden Angriff.\",\"befund_route_offen_themes\":\"Die Themenliste ist lesbar || {pfad} hat mit 200 geantwortet. In einer Standardinstallation ist diese Route nicht \u00f6ffentlich.\",\"befund_inhalte_offen\":\"Beitr\u00e4ge sind lesbar || {anzahl} Eintr\u00e4ge unter \\\/wp\\\/v2\\\/posts. F\u00fcr ver\u00f6ffentlichte Inhalte ist genau das so vorgesehen.\",\"befund_verzeichnis_offen\":\"Das Verzeichnis selbst ist lesbar || {routen} Routen in {raeume} Namensr\u00e4umen. Das ist die Voreinstellung \u2014 und zugleich eine vollst\u00e4ndige Liste der Module, die Routen anmelden.\",\"befund_schreibende_routen\":\"{anzahl} Routen nehmen schreibende Methoden an || So steht es im Verzeichnis. Ob sie etwas zulassen, entscheidet ihre eigene Rechtepr\u00fcfung, nicht diese Liste.\",\"befund_fremde_namensraeume\":\"{anzahl} Namensr\u00e4ume jenseits des WordPress-Kerns || Etwa {raeume}. Jeder stammt aus einem Erweiterungsmodul und benennt es.\",\"befund_ohne_huebsche_adressen\":\"Das Verzeichnis antwortet nur unter ?rest_route= || Sprechende Adressen sind abgeschaltet, die REST-Schnittstelle ist \u00fcber die Abfragezeichenfolge erreichbar.\",\"befund_seitendaten\":\"Seitenname und Beschreibung stehen im Verzeichnis || Das ist so vorgesehen und \u00f6ffentlich \u2014 und es steht auch im Verzeichnis einer Seite, die sonst nichts preisgibt.\",\"fehler_adresse\":\"Diese Adresse l\u00e4sst sich nicht verwenden.\",\"fehler_netz\":\"Der Server war nicht erreichbar.\",\"fehler_antwort\":\"Die Antwort war nicht lesbar.\",\"fehler_captcha\":\"Die Spam-Pr\u00fcfung ist fehlgeschlagen. Ein Neuladen hilft meistens.\",\"fehler_kein_token\":\"Die Spam-Pr\u00fcfung hat kein Merkmal geliefert.\",\"fehler_zu_viele\":\"Stundengrenze von {limit} Abfragen erreicht.\",\"fehler_zaehler\":\"Der Z\u00e4hler steht nicht zur Verf\u00fcgung.\",\"fehler_pruefdienst\":\"Die Spam-Pr\u00fcfung steht nicht zur Verf\u00fcgung.\",\"fehler_aufbau\":\"Das Werkzeug ist falsch eingerichtet.\",\"fehler_methode\":\"Falsche Anfrageart.\",\"fehler_eingabe\":\"Die Eingabe war nicht lesbar.\",\"fehler_unbekannt\":\"Etwas ist schiefgegangen.\",\"grund_leer\":\"Es wurde keine Adresse angegeben.\",\"grund_zu_lang\":\"Die Adresse ist zu lang.\",\"grund_schema\":\"Nur http und https funktionieren.\",\"grund_unlesbar\":\"Die Adresse lie\u00df sich nicht zerlegen.\",\"grund_benutzerinfo\":\"Adressen mit Benutzernamen werden abgelehnt.\",\"grund_gesperrter_bereich\":\"Diese Adresse zeigt in ein privates Netz.\",\"grund_kein_punkt\":\"Ein Hostname braucht einen Punkt.\",\"grund_hostform\":\"N\u00f6tig ist ein Domainname, keine IP-Adresse.\",\"grund_port\":\"Dieser Port ist nicht zugelassen.\",\"grund_kein_dns\":\"Der Name l\u00f6st nicht auf.\"};<\/p>\n<p>    var ENDPUNKT = '\/lw-restrouten.php';\n    var SITEKEY = '6LcrPkEtAAAAAPo1QCOf-IIM2fCL0UfdJz4y2iSY';\n    var STUFEN = ['hoch', 'mittel', 'niedrig', 'info', 'gut'];\n    var ZUSTAENDE = ['offen', 'geschuetzt', 'fehlt', 'gesperrt', 'fehler'];\n    var PROBEN = ['users', 'settings', 'plugins', 'themes', 'posts', 'pages', 'media', 'comments', 'types', 'search'];<\/p>\n<p>    function liste(w) { return Array.isArray(w) ? w : []; }\n    function zahl(w) { return (typeof w === 'number' && isFinite(w)) ? w : null; }\n    function text(schluessel, daten) {\n        var t = T[schluessel];\n        if (typeof t !== 'string') { return null; }\n        return t.replace(\/\\{([a-z_0-9]+)\\}\/g, function (m, k) {\n            return (daten && daten[k] !== undefined && daten[k] !== null) ? String(daten[k]) : m;\n        });\n    }<\/p>\n<p>    function bewerten(antwort) {\n        var a = antwort || {};\n        if (a.fehler) { return { fehler: String(a.fehler), grund: a.grund || null, limit: zahl(a.limit) }; }\n        var befunde = liste(a.befunde).map(function (f) {\n            return { key: String(f.key || ''), stufe: STUFEN.indexOf(f.stufe) === -1 ? 'info' : f.stufe, daten: (f.daten && typeof f.daten === 'object') ? f.daten : {} };\n        });\n        var gruppen = {};\n        STUFEN.forEach(function (s) { gruppen[s] = befunde.filter(function (f) { return f.stufe === s; }); });\n        var rohProben = (a.proben && typeof a.proben === 'object') ? a.proben : {};\n        var proben = [];\n        PROBEN.forEach(function (k) {\n            var p = rohProben[k];\n            if (!p) { return; }\n            proben.push({ key: k, pfad: String(p.pfad || ''), status: zahl(p.status),\n                zustand: ZUSTAENDE.indexOf(p.zustand) === -1 ? 'fehler' : p.zustand, anzahl: zahl(p.anzahl) });\n        });\n        var s = (a.seite && typeof a.seite === 'object') ? a.seite : {};\n        return {\n            fehler: null,\n            basis: a.basis ? String(a.basis) : '',\n            erreichbar: !!a.erreichbar,\n            weg: a.weg === 'rest_route' ? 'rest_route' : 'wp-json',\n            status: zahl(a.status),\n            urteil: (a.urteil === 'gut' || a.urteil === 'warnung' || a.urteil === 'kritisch') ? a.urteil : 'kritisch',\n            routen: zahl(a.routen_gesamt) || 0,\n            raeume: zahl(a.raeume_gesamt) || 0,\n            schreibend: zahl(a.schreibend) || 0,\n            namensraeume: liste(a.namensraeume).map(function (x) { x = x || {}; return { raum: String(x.raum || ''), routen: zahl(x.routen) || 0 }; }),\n            proben: proben,\n            seite: { name: s.name ? String(s.name) : null, beschreibung: s.beschreibung ? String(s.beschreibung) : null,\n                sprache: s.sprache ? String(s.sprache) : null, zeitzone: s.zeitzone ? String(s.zeitzone) : null,\n                anmeldung: liste(s.anmeldung).map(String) },\n            befunde: befunde, stufengruppen: gruppen,\n            dauer: zahl(a.dauer_ms), limitRest: zahl(a.limit_rest)\n        };\n    }<\/p>\n<p>    function skriptLaden() {\n        return new Promise(function (auf) {\n            if (window.grecaptcha) { auf(true); return; }\n            var s = document.createElement('script');\n            s.src = 'https:\/\/www.google.com\/recaptcha\/api.js?render=' + SITEKEY;\n            s.onload = function () { auf(true); }; s.onerror = function () { auf(false); };\n            document.head.appendChild(s);\n            setTimeout(function () { auf(!!window.grecaptcha); }, 8000);\n        });\n    }\n    function tokenHolen() {\n        return skriptLaden().then(function (da) {\n            if (!da || !window.grecaptcha || !window.grecaptcha.ready) { return null; }\n            return new Promise(function (auf) {\n                var fertig = false;\n                function einmal(w) { if (!fertig) { fertig = true; auf(w); } }\n                setTimeout(function () { einmal(null); }, 12000);\n                try {\n                    window.grecaptcha.ready(function () {\n                        if (fertig) { return; }\n                        if (!window.grecaptcha.execute) { einmal(null); return; }\n                        window.grecaptcha.execute(SITEKEY, { action: 'restrouten' }).then(function (t) { einmal(t || null); }, function () { einmal(null); });\n                    });\n                } catch (e) { einmal(null); }\n            });\n        }, function () { return null; });\n    }\n    function abfragen(url) {\n        return tokenHolen().then(function (token) {\n            return fetch(ENDPUNKT, { method: 'POST', headers: { 'Content-Type': 'application\/json' }, body: JSON.stringify({ url: url, token: token || '' }) })\n                .then(function (r) { return r.json().then(function (j) { return j; }, function () { return { fehler: 'antwort' }; }); }, function () { return { fehler: 'netz' }; });\n        });\n    }<\/p>\n<p>    window.LW_TEST = window.LW_TEST || {};\n    window.LW_TEST.RS = { bewerten: bewerten, darstellen: null, text: text,\n        ENDPUNKT: ENDPUNKT, STUFEN: STUFEN, ZUSTAENDE: ZUSTAENDE, PROBEN: PROBEN, T: T };<\/p>\n<p>    var btn = document.getElementById('rs-btn');\n    var out = document.getElementById('rs-ausgabe');\n    if (!btn || !out) { return; }<\/p>\n<p>    function el(tag, stil, txt) { var e = document.createElement(tag); if (stil) { e.setAttribute('style', stil); } if (txt !== undefined && txt !== null) { e.textContent = txt; } return e; }\n    function wert(id) { var e = document.getElementById(id); return e ? e.value : ''; }\n    var UEBERSCHRIFT = 'font-family: \"Nunito Sans\", sans-serif; font-weight: 700; color: var(--text-primary, #e8e8ee); font-size: 0.95rem; margin: 22px 0 8px;';\n    var ZELLE = 'padding: 5px 12px 5px 0; color: var(--text-secondary, #a0a0b0); font-size: 0.87rem;';\n    var ZELLE_WERT = 'padding: 5px 12px 5px 0; color: var(--text-primary, #e8e8ee); font-size: 0.87rem; font-family: monospace; word-break: break-all;';\n    var KASTEN = 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-radius: 8px; padding: 14px 16px; margin: 0 0 10px;';\n    var GUT = ' color: #7ee787;', WARN = ' color: #ffa94d;', ROT = ' color: #ff7b72;', GRAU = ' color: #8a8a99;';\n    var FARBEN = { hoch: '#ff7b72', mittel: '#ffa94d', niedrig: '#e3b341', info: '#8a8a99', gut: '#7ee787' };\n    var URTEIL = { gut: GUT, warnung: WARN, kritisch: ROT };\n    var ZUSTAND_FARBE = { offen: WARN, geschuetzt: GUT, fehlt: GRAU, gesperrt: GRAU, fehler: ROT };\n    function gitter(sp) { return el('div', 'display: grid; grid-template-columns: ' + sp + '; gap: 0 18px; align-items: baseline;'); }\n    function paar(g, n, w, stil) { g.appendChild(el('div', ZELLE, n)); g.appendChild(el('div', ZELLE_WERT + (stil || ''), w)); }<\/p>\n<p>    function darstellen(b, ziel) {\n        ziel.innerHTML = '';\n        if (b.fehler) {\n            var txt = T['fehler_' + b.fehler] || T.fehler_unbekannt;\n            if (b.grund && T['grund_' + b.grund]) { txt = txt + ' ' + T['grund_' + b.grund]; }\n            if (b.limit !== null) { txt = txt.replace('{limit}', String(b.limit)); }\n            ziel.appendChild(el('p', ZELLE + WARN + ' margin: 0;', txt));\n            return;\n        }<\/p>\n<p>        ziel.appendChild(el('div', 'font-size: 1.05rem; font-weight: 700; margin: 0 0 6px;' + URTEIL[b.urteil], T['urteil_' + b.urteil]));\n        if (!b.erreichbar) {\n            ziel.appendChild(el('p', ZELLE + ' margin: 0 0 12px;', T.kein_verzeichnis_text));\n        } else {\n            ziel.appendChild(el('p', ZELLE + ' margin: 0 0 12px;', text('zusammenfassung', { routen: b.routen, raeume: b.raeume, schreibend: b.schreibend })));<\/p>\n<p>            \/\/ --- Die Stichproben: der eigentliche Kern\n            ziel.appendChild(el('div', UEBERSCHRIFT, T.h_proben));\n            ziel.appendChild(el('p', ZELLE + ' margin: 0 0 8px;', T.proben_hinweis));\n            var hp = el('div', 'overflow-x: auto;');\n            var gp = gitter('auto auto auto auto');\n            [T.spalte_route, T.spalte_zustand, T.spalte_status, T.spalte_anzahl].forEach(function (s) {\n                gp.appendChild(el('div', ZELLE + ' font-weight: 700; color: var(--text-primary, #e8e8ee); white-space: nowrap;', s));\n            });\n            b.proben.forEach(function (p) {\n                gp.appendChild(el('div', ZELLE_WERT + ' white-space: nowrap;', p.pfad));\n                gp.appendChild(el('div', ZELLE_WERT + ZUSTAND_FARBE[p.zustand] + ' white-space: nowrap;', T['zustand_' + p.zustand]));\n                gp.appendChild(el('div', ZELLE_WERT + GRAU, p.status === null ? '-' : String(p.status)));\n                gp.appendChild(el('div', ZELLE_WERT + GRAU, p.anzahl === null ? '-' : String(p.anzahl)));\n            });\n            hp.appendChild(gp);\n            ziel.appendChild(hp);<\/p>\n<p>            \/\/ --- Namensraeume\n            if (b.namensraeume.length) {\n                ziel.appendChild(el('div', UEBERSCHRIFT, T.h_raeume));\n                var hr = el('div', 'overflow-x: auto;');\n                var gr = gitter('auto auto');\n                [T.spalte_raum, T.spalte_routen].forEach(function (s) {\n                    gr.appendChild(el('div', ZELLE + ' font-weight: 700; color: var(--text-primary, #e8e8ee); white-space: nowrap;', s));\n                });\n                b.namensraeume.forEach(function (n) {\n                    gr.appendChild(el('div', ZELLE_WERT + ' white-space: nowrap;', n.raum));\n                    gr.appendChild(el('div', ZELLE_WERT + GRAU, String(n.routen)));\n                });\n                hr.appendChild(gr);\n                ziel.appendChild(hr);\n            }<\/p>\n<p>            \/\/ --- Was das Verzeichnis ueber die Seite sagt\n            ziel.appendChild(el('div', UEBERSCHRIFT, T.h_seite));\n            var gs = gitter('auto auto');\n            paar(gs, T.zeile_name, b.seite.name || '-', GRAU);\n            paar(gs, T.zeile_beschreibung, b.seite.beschreibung || '-', GRAU);\n            paar(gs, T.zeile_sprache, b.seite.sprache || '-', GRAU);\n            paar(gs, T.zeile_zeitzone, b.seite.zeitzone || '-', GRAU);\n            paar(gs, T.zeile_anmeldung, b.seite.anmeldung.length ? b.seite.anmeldung.join(', ') : T.keine_anmeldung, GRAU);\n            paar(gs, T.zeile_weg, b.weg === 'rest_route' ? T.weg_rest_route : T.weg_wp_json, GRAU);\n            if (b.dauer !== null) { paar(gs, T.zeile_dauer, b.dauer + ' ms', GRAU); }\n            if (b.limitRest !== null) { paar(gs, T.zeile_limit, String(b.limitRest), GRAU); }\n            ziel.appendChild(gs);\n        }<\/p>\n<p>        \/\/ --- Befunde\n        ziel.appendChild(el('div', UEBERSCHRIFT, T.h_befunde));\n        var irgendwas = false;\n        STUFEN.forEach(function (s) {\n            var g2 = b.stufengruppen[s];\n            if (!g2.length) { return; }\n            irgendwas = true;\n            ziel.appendChild(el('div', 'font-weight: 700; font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.5px; margin: 14px 0 6px; color: ' + FARBEN[s] + ';', T['stufe_' + s] + ' (' + g2.length + ')'));\n            g2.forEach(function (f) {\n                var k = el('div', KASTEN + ' border-left: 3px solid ' + FARBEN[s] + ';');\n                var d = {};\n                Object.keys(f.daten).forEach(function (n) {\n                    var w = f.daten[n];\n                    d[n] = Array.isArray(w) ? w.join(', ') : w;\n                });\n                var t = text('befund_' + f.key, d) || f.key;\n                var teile = t.split(' || ');\n                k.appendChild(el('div', 'color: var(--text-primary, #e8e8ee); font-size: 0.9rem; font-weight: 700;', teile[0]));\n                if (teile[1]) { k.appendChild(el('div', ZELLE + ' padding: 6px 0 0; line-height: 1.55;', teile[1])); }\n                ziel.appendChild(k);\n            });\n        });\n        if (!irgendwas) { ziel.appendChild(el('p', ZELLE + ' margin: 0;', T.keine_befunde)); }\n    }\n    window.LW_TEST.RS.darstellen = darstellen;<\/p>\n<p>    var laeuft = false;\n    btn.addEventListener('click', function () {\n        if (laeuft) { return; }\n        laeuft = true; btn.disabled = true;\n        out.innerHTML = '';\n        out.appendChild(el('p', ZELLE + GRAU + ' margin: 0;', T.laeuft));\n        abfragen(wert('rs-url')).then(function (a) { darstellen(bewerten(a), out); laeuft = false; btn.disabled = false; },\n            function () { darstellen(bewerten({ fehler: 'netz' }), out); laeuft = false; btn.disabled = false; });\n    });\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Liest das Routenverzeichnis unter \/wp-json\/, z\u00e4hlt Routen und Namensr\u00e4ume und ruft danach zehn bekannte Routen ohne jede Anmeldung ab \u2014 denn das Verzeichnis sagt nur, welche Routen es gibt, nie wer sie lesen darf. Erst dieser zweite Schritt trennt eine aufgef\u00fchrte Route von einer offenen.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":9283,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"tags":[92759,92071,92277],"class_list":["post-15725","page","type-page","status-publish","hentry","tag-web-development-de","tag-web-security-de","tag-wordpress-de"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>WordPress-REST-Routeninventar: was eine Seite ohne Anmeldung herausgibt - Lukas Wojcik - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wordpress-rest-route-inventory\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"WordPress-REST-Routeninventar: was eine Seite ohne Anmeldung herausgibt - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Liest das Routenverzeichnis unter \/wp-json\/, z\u00e4hlt Routen und Namensr\u00e4ume und ruft danach zehn bekannte Routen ohne jede Anmeldung ab \u2014 denn das Verzeichnis sagt nur, welche Routen es gibt, nie wer sie lesen darf. Erst dieser zweite Schritt trennt eine aufgef\u00fchrte Route von einer offenen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wordpress-rest-route-inventory\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/wordpress-rest-route-inventory\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/wordpress-rest-route-inventory\\\/\",\"name\":\"WordPress-REST-Routeninventar: was eine Seite ohne Anmeldung herausgibt - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-09-06T09:09:51+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/wordpress-rest-route-inventory\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/wordpress-rest-route-inventory\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/wordpress-rest-route-inventory\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Toolbox\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/toolbox-2\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"WordPress-REST-Routeninventar: was eine Seite ohne Anmeldung herausgibt\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"luky\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"luky\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"WordPress-REST-Routeninventar: was eine Seite ohne Anmeldung herausgibt - Lukas Wojcik - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wordpress-rest-route-inventory\/","og_locale":"en_US","og_type":"article","og_title":"WordPress-REST-Routeninventar: was eine Seite ohne Anmeldung herausgibt - Lukas Wojcik - Blog","og_description":"Liest das Routenverzeichnis unter \/wp-json\/, z\u00e4hlt Routen und Namensr\u00e4ume und ruft danach zehn bekannte Routen ohne jede Anmeldung ab \u2014 denn das Verzeichnis sagt nur, welche Routen es gibt, nie wer sie lesen darf. Erst dieser zweite Schritt trennt eine aufgef\u00fchrte Route von einer offenen.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wordpress-rest-route-inventory\/","og_site_name":"Lukas Wojcik - Blog","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wordpress-rest-route-inventory\/","url":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wordpress-rest-route-inventory\/","name":"WordPress-REST-Routeninventar: was eine Seite ohne Anmeldung herausgibt - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-09-06T09:09:51+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wordpress-rest-route-inventory\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wordpress-rest-route-inventory\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wordpress-rest-route-inventory\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Toolbox","item":"https:\/\/www.lukaswojcik.com\/blog\/toolbox-2\/"},{"@type":"ListItem","position":3,"name":"WordPress-REST-Routeninventar: was eine Seite ohne Anmeldung herausgibt"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"luky","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"luky"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/15725","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=15725"}],"version-history":[{"count":0,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/15725\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9283"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=15725"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=15725"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}