Các bước thực tế
Mở trang cần kiểm tra và bảng điều khiển dành cho nhà phát triển của trình duyệt. Với công cụ kiểm tra tràn trên di động, trước tiên hãy bật chế độ responsive.
Xem xét mã, dán toàn bộ đoạn script vào console rồi nhấn Enter. Script đọc trang hiện tại; chỉ công cụ kiểm tra metadata sitemap và các bộ kiểm tra cùng origin mới gửi request có giới hạn.
Xem kết quả trong console hoặc CSV/JSON tải xuống. Chính sách trình duyệt, trạng thái xác thực và phương thức máy chủ không được hỗ trợ có thể khiến một số phép kiểm tra chưa kết luận được.
Script dành cho console của trình duyệt
Xem xét trước khi chạy. Script đọc trang hiện tại; chỉ các lần kiểm tra sitemap và liên kết mới gửi request cùng origin có giới hạn. Request không gửi cookie; script không thay đổi nội dung website.
(async () => {
const MAX_URLS = 200;
const CONCURRENCY = 4;
const TIMEOUT_MS = 10000;
const deadline = Date.now() + 45000;
const origin = location.origin;
const allUrls = [...new Set([...document.links].map((link) => {
try { const url = new URL(link.href); url.hash = ''; return url.origin === origin && /^https?:$/.test(url.protocol) ? url.href : ''; } catch { return ''; }
}).filter(Boolean))];
const urls = allUrls.slice(0, MAX_URLS);
const results = new Array(urls.length);
let cursor = 0;
async function worker() {
while (cursor < urls.length && Date.now() < deadline) {
const index = cursor++;
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), Math.min(TIMEOUT_MS, deadline - Date.now()));
try {
const response = await fetch(urls[index], { method: 'HEAD', credentials: 'omit', redirect: 'follow', cache: 'no-store', signal: controller.signal });
results[index] = { url: urls[index], status: response.status, finalUrl: response.url, result: response.status === 405 || response.status === 501 ? 'HEAD unsupported; check manually' : response.ok ? 'OK' : 'HTTP error' };
} catch (error) {
results[index] = { url: urls[index], status: '', finalUrl: '', result: error.name === 'AbortError' ? 'timeout' : 'blocked or network error' };
} finally { clearTimeout(timer); }
}
}
await Promise.all(Array.from({ length: Math.min(CONCURRENCY, urls.length) }, worker));
for (let index = 0; index < urls.length; index++) if (!results[index]) results[index] = { url: urls[index], status: '', finalUrl: '', result: 'not checked: 45-second runtime limit' };
console.table(results);
if (allUrls.length > MAX_URLS) console.warn('Only the first ' + MAX_URLS + ' of ' + allUrls.length + ' unique internal URLs were checked.');
console.info('Checked ' + results.filter((row) => !row.result.startsWith('not checked')).length + ' of ' + urls.length + ' unique same-origin links with HEAD requests. Limits: ' + MAX_URLS + ' links and 45 seconds. Unsupported HEAD, access restrictions, or browser policy can make a result inconclusive. No cookies were sent.');
})();