استخدم هذه الخطوات كقائمة تحقق عملية، وكيّفها مع أدلة المشروع ونطاقه وقيوده.
خطوات عملية
- افتح الصفحة التي تريد فحصها ووحدة تحكم مطوري المتصفح. استخدم أولًا وضع العرض المتجاوب لفاحص التجاوز على الهاتف المحمول.
- راجع الشيفرة، والصق المقتطف كاملًا في وحدة التحكم، ثم اضغط Enter. تقرأ الأداة الصفحة الحالية؛ ولا تجري طلبات محدودة إلا أداة بيانات sitemap الوصفية وأدوات فحص الأصل نفسه (البروتوكول والنطاق والمنفذ).
- راجع مخرجات وحدة التحكم أو ملف CSV/JSON الذي تم تنزيله. قد تجعل سياسات المتصفح والمصادقة وطرق الخادم غير المدعومة بعض الفحوص غير حاسمة.
(async () => {
const MAX_VARIANTS = 30;
const deadline = Date.now() + 30000;
const currentCanonical = new URL(document.querySelector('link[rel="canonical"]')?.href || location.href, location.href).href;
const tags = [...document.querySelectorAll('link[rel="alternate"][hreflang][href]')].slice(0, MAX_VARIANTS);
const rows = [];
for (const tag of tags) {
const target = new URL(tag.href, location.href);
const item = { language: tag.hreflang, url: target.href, sameOrigin: target.origin === location.origin, reciprocal: 'not checked' };
if (item.sameOrigin) {
if (Date.now() >= deadline) { item.reciprocal = 'skipped: 30-second runtime limit'; rows.push(item); continue; }
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), Math.min(5000, deadline - Date.now()));
try {
const response = await fetch(target.href, { credentials: 'omit', redirect: 'follow', signal: controller.signal });
if (!response.ok || new URL(response.url).origin !== location.origin) throw new Error('HTTP ' + response.status + ' or cross-origin redirect');
const doc = new DOMParser().parseFromString(await response.text(), 'text/html');
const reciprocal = [...doc.querySelectorAll('link[rel="alternate"][hreflang][href]')].some((link) => {
try { return new URL(link.href, target.href).href === currentCanonical; } catch { return false; }
});
item.reciprocal = reciprocal ? 'yes' : 'missing';
} catch (error) { item.reciprocal = error.name === 'AbortError' ? 'timeout' : 'could not check'; }
finally { clearTimeout(timer); }
}
rows.push(item);
}
console.table(rows);
console.info('Current canonical:', currentCanonical, '· hreflang variants found:', tags.length);
if (Date.now() >= deadline) console.warn('The 30-second runtime limit was reached; remaining links were not checked.');
if (tags.length >= MAX_VARIANTS) console.warn('Only the first ' + MAX_VARIANTS + ' language variants were checked.');
if (!tags.length) console.warn('No link rel=\"alternate\" hreflang entries were found.');
console.info('Cross-origin and inaccessible pages are not fetched. A “missing” reciprocal link may also result from a canonical URL variant or redirect; review it manually.');
})();راجع الشيفرة قبل تشغيلها. تقرأ الصفحة الحالية؛ ولا تجري طلبات محدودة إلى الأصل نفسه (البروتوكول والنطاق والمنفذ) إلا فحوص sitemap والروابط. لا ترسل الطلبات ملفات تعريف الارتباط، ولا تغيّر الشيفرة محتوى الموقع.