تخطَّ إلى المحتوى

١٢ يوليو ٢٠٢٦

حل خطأ localhost refused to connect بالعربي

شارك المقال:

كتبت npm run dev (أو ظننت أنك كتبتها 😄)، فتحت المتصفح، فصفعك:

This site can't be reached
localhost refused to connect.
ERR_CONNECTION_REFUSED

أول جدار يصطدم به كل من يشغّل مشروعه الأول محليًا. الخبر الجيد: هذا أصدق خطأ في الويب — معناه حرفيًا: «طرقتُ المنفذ، لا أحد يستمع خلفه».

افهم الرسالة أولًا

عندما تفتح localhost:3000 يحاول المتصفح الاتصال بخادم على منفذ 3000 في جهازك نفسه. الرفض الفوري (refused) يعني أن نظام التشغيل ردّ: «لا يوجد أي برنامج يستمع هنا». لا علاقة للإنترنت ولا للواي فاي — الرحلة كلها داخل جهازك.

قارنه بجيرانه: 404 و500 يعنيان أن خادمًا موجودًا وردّ — أما هنا فلا خادم أصلًا.

الأسباب الخمسة بالترتيب الواقعي

السببكيف تتأكدالحل
الخادم غير شغّال أصلًالا سطر Ready بالطرفيةشغّله 😄
انهار لحظة الإقلاعرسالة خطأ حمراء بالطرفيةاقرأها وعالجها
منفذ مختلف«3001» بالطرفية و«3000» بالمتصفحطابق الرقم
داخل Docker بلا نشريعمل بالحاوية فقط-p 3000:3000
عنوان استماع مقيّديعمل بـ 127.0.0.1 لا localhostجرّب الاثنين / host 0.0.0.0

1) الخادم ببساطة غير شغّال

الطرفية أُغلقت، أو أوقفته بـ Ctrl+C ونسيت، أو فتحت نافذة جديدة وظننت القديمة تعمل. العلامة القاطعة: طرفية الخادم يجب أن تعرض سطرًا حيًّا مثل:

✓ Ready on http://localhost:3000

لا سطر؟ لا خادم — شغّله وابقِ الطرفية مفتوحة.

2) انهار أثناء الإقلاع — والجواب فوق مباشرة

شغّلته فعلًا، لكنه مات خلال ثانية برسالة حمراء لم تقرأها. أشهر رسالتين:

القاعدة: اقرأ آخر 10 أسطر في الطرفية قبل فتح المتصفح.

3) المنفذ غير الذي تظن

كثير من الأدوات تبدّل المنفذ تلقائيًا عندما يكون الافتراضي محجوزًا:

⚠ Port 3000 is in use, using available port 3001 instead.

وأنت ما زلت تفتح 3000. الحل: انسخ الرابط من الطرفية نفسها — لا تكتبه من الذاكرة.

4) يعمل داخل Docker — والباب مغلق للمضيف

الخادم يستمع داخل الحاوية، وجهازك عالم آخر. بلا نشر المنفذ لن يصلك شيء:

docker run -p 3000:3000 my-app   # المضيف:الحاوية

وتذكّر داخل الحاوية أن يستمع تطبيقك على 0.0.0.0 لا على 127.0.0.1 — وإلا رفض الاتصالات الآتية من خارج الحاوية حتى مع النشر. (وتعارضات المنفذ نفسها؟ دليل Docker هنا.)

5) localhost مقابل 127.0.0.1

حالات نادرة لكنها محيّرة: الخادم يستمع على IPv4 (127.0.0.1) والنظام يحل localhost إلى IPv6 (::1) أولًا. جرّب http://127.0.0.1:3000 مباشرة — إن عمل، ثبّت host الخادم أو استخدم الرقم مباشرة.

قائمة تحقّق سريعة

  • الطرفية تعرض سطر Ready/Listening الآن؟
  • إن مات عند الإقلاع: اقرأ الخطأ — EADDRINUSE أو module ناقص غالبًا.
  • انسخ الرابط والمنفذ من الطرفية حرفيًا.
  • Docker؟ → -p للنشر + استماع على 0.0.0.0 داخل الحاوية.
  • جرّب 127.0.0.1 بدل localhost قبل اتهام أي شيء آخر.

الخلاصة

refused to connect لا يكذب: لا خادم يستمع حيث تطرق. الحل دائمًا في جهة التشغيل — شغّل، اقرأ الطرفية، طابق المنفذ، وانشر منفذ Docker — ولن تراه مجددًا إلا عن نسيان مشروع 😄

أساسيات الخوادم والمنافذ من الجذور في مسار الشبكات بالعربي ومسار Node.js، وأكمل السلسلة مع حل EADDRINUSE.

📚 مصادر رسمية للتعمّق: توثيق HTTP والشبكات على MDN

الأسئلة الشائعة

ما الفرق بين هذا الخطأ وخطأ 404 أو 500؟

404 و500 تعني أن خادمًا موجودًا واستقبل طلبك ثم ردّ (بصفحة غير موجودة أو بعطل داخلي). أما refused to connect فتعني أنه لا يوجد خادم أصلًا على هذا العنوان والمنفذ — الطلب لم يصل لأي أحد. لذلك حلّه دائمًا في «تشغيل الخادم» لا في الكود المستقبِل.

الطرفية تقول الخادم شغال والمتصفح يرفض — كيف؟

أشهر ثلاثة أسباب: المنفذ بالطرفية غير الذي كتبته بالمتصفح (شغّال على 3001 وأنت تفتح 3000)، أو الخادم داخل Docker/WSL بلا نشر منفذ للمضيف، أو الخادم يستمع على 127.0.0.1 حصرًا وأنت تدخل من IP الشبكة (أو العكس). طابق الرقم والعنوان حرفيًا مع سطر Listening.

هل localhost و 127.0.0.1 نفس الشيء دائمًا؟

عمليًا نعم — localhost اسم يشير إلى 127.0.0.1 (أو ::1 في IPv6). لكن بعض الإعدادات تجعل خادمًا يستمع على أحدهما دون الآخر، وبعض الأنظمة تحل localhost إلى IPv6 أولًا بينما الخادم يستمع على IPv4 فقط. عند الشك جرّب 127.0.0.1 مباشرة — إن عمل فمشكلتك في حل الاسم/واجهة الاستماع.

اقرأ أيضًا

تصفّح كل المقالات في المدوّنة، أو ابدأ التعلّم من المسارات و خرائط الطريق.