Skip to content

Ports et localhost

💡 Guide d'apprentissage : Lorsque vous exécutez npm run dev et que le terminal affiche http://localhost:5173, vous êtes-vous déjà demandé : qu'est-ce que localhost ? Que représente 5173 ? Pourquoi obtient-on parfois l'erreur EADDRINUSE ? Ce chapitre va expliquer en profondeur ces concepts que vous voyez tous les jours en développement mais que vous n'avez jamais vraiment approfondis.

Avant de commencer, il est conseillé de poser deux « briques de base » :


0. Introduction : qu'est-ce que ce fameux localhost:5173 qu'on voit tous les jours ?

1
2
3
4
5
1. You run npm run dev
Terminal
$ npm run dev

> vite

  准备就绪...
Listening
Browser
等待你打开Browser...
💡 You type the start command in terminal
What is an HTTP Server?
🏪
Imagine a service windowHTTP 服务器就像一个"永远开着的服务窗口"——它一直等在那里,有人来问就回答,没人来就静静等着。
📋
Only understands one "code"这个窗口只听得懂 HTTP 协议的请求格式(比如 GET /index.html),然后把对应的文件内容返回给你。
⚙️
Dev Server = Enhanced WindowVite、Webpack 的开发服务器不只是"原样返回文件",它还会即时编译你的代码(Vue → JS、TS → JS、Sass → CSS),然后再返回给Browser。
One-line Summary:Dev server = An HTTP server running on localhost + Real-time code compiler. It listens on a port, and when browser requests, it returns the compiled code.

Le quotidien de chaque développeur est indissociable de cette ligne de sortie :

➜  Local:   http://localhost:5173/

Mais vous êtes-vous déjà demandé ce que cache cette courte ligne ? Elle contient plusieurs concepts clés :

  • http:// → protocole de communication (dans quelle langue dialoguer)
  • localhost → adresse cible (qui contacter)
  • :5173 → numéro de port (une fois trouvé, à quelle porte frapper)

Comprendre ces trois éléments vous permettra de résoudre 90 % des problèmes réseau en environnement de développement. Décortiquons-les un par un.


1. Qu'est-ce qu'un port ? (L'IP est l'immeuble, le port est le numéro d'appartement)

1.1 Une analogie intuitive

Imaginez un serveur comme un immeuble :

  • L'adresse IP (par exemple 192.168.1.100) est l'adresse de l'immeuble — elle vous dit « dans quel immeuble aller ».
  • Le numéro de port (par exemple :80) est le numéro d'appartement dans l'immeuble — il vous dit « dans quelle pièce entrer ».

Un immeuble peut abriter simultanément un restaurant (pièce 80), un café (pièce 443), un bureau (pièce 22). De même, un ordinateur peut exécuter simultanément un serveur web, une base de données et un service SSH, chacun occupant un port différent.

👇 Essayez par vous-même : Cliquez sur les « plaques de porte » ci-dessous pour simuler une connexion vers différents ports. Observez ce qui se passe lorsque le port est « ouvert » (un programme écoute) et lorsqu'il est « fermé ».

Select a "building":
Web Server BuildingIP: 192.168.1.100
80
HTTPWeb access entry
🟢 Listening
443
HTTPSEncrypted web entry
🟢 Listening
22
SSHRemote management channel
🟢 Listening
3306
MySQLDatabase (closed)
🔴 Closed
Core Analogy:IP 地址 = 大楼地址,端口号 = 房间门牌号。一台电脑上可以同时运行多个服务,每个服务"占用"一个端口号,就像同一栋大楼里的不同房间。

1.2 Plage de valeurs des numéros de port

Un numéro de port est un entier compris entre 0 et 65535 (soit 65536 ports au total). Cette plage est divisée en trois intervalles :

IntervallePlageUsageExemples
Ports système0 – 1023Réservés aux protocoles standards, les utilisateurs ordinaires ne peuvent pas les occuper librement80 (HTTP), 443 (HTTPS), 22 (SSH)
Ports enregistrés1024 – 49151Attribués aux applications courantes3306 (MySQL), 5432 (PostgreSQL), 6379 (Redis)
Ports dynamiques49152 – 65535Attribués temporairement par le système d'exploitationQuand le navigateur envoie une requête, le système attribue aléatoirement un port source

Pourquoi votre serveur de développement aime-t-il utiliser 3000, 5173, 8080 ? Parce que ces numéros sont dans la plage des « ports enregistrés », ne nécessitent pas de privilèges administrateur pour écouter et entrent rarement en conflit avec les services système.

1.3 Référence rapide des ports courants en développement

👇 Essayez par vous-même : Saisissez un numéro de port ou un nom de service pour rechercher, cliquez sur une ligne pour afficher des exemples d'utilisation.

PortServiceDescriptionExposure Risk
80HTTP网页访问(未加密)安全
443HTTPS网页访问(加密)安全
22SSH安全远程登录注意
21FTP文件传输敏感
3306MySQLMySQL 数据库敏感
5432PostgreSQLPostgreSQL 数据库敏感
27017MongoDBMongoDB 数据库敏感
6379RedisRedis 缓存敏感
3000Node/ReactNode.js / React 开发服务器安全
5173ViteVite 开发服务器安全
8080通用 HTTPHTTP 备用端口 / 代理安全
8000Django/PythonDjango / Python HTTP 服务安全
5000FlaskFlask 开发服务器安全
4200AngularAngular 开发服务器安全
53DNS域名解析注意
25SMTP邮件发送注意
0 – 1023
System PortsReserved for standard services (HTTP, SSH, etc.), regular users cannot occupy.
1024 – 49151
Registered PortsFor common applications (MySQL 3306, Redis 6379, etc.), most encountered in development.
49152 – 65535
Dynamic PortsTemporarily assigned by OS, like when your browser makes requests, system randomly assigns one.
Security Alert:数据库端口(3306、5432、27017、6379)绝对不要直接暴露到公网!生产环境应只允许内网访问或通过 SSH 隧道连接。

2. Qu'est-ce que localhost ? (Se chercher soi-même)

2.1 Le concept central de « boucle locale »

localhost est un nom de domaine spécial qui pointe toujours vers votre propre ordinateur.

Lorsque vous saisissez http://localhost:3000 dans votre navigateur, voici ce qui se passe :

  1. Le navigateur demande au système d'exploitation : « Quelle est l'IP de localhost ? »
  2. Le système d'exploitation répond directement : « 127.0.0.1 » (pas besoin de consulter le DNS en ligne)
  3. Le paquet de données est envoyé vers 127.0.0.1, mais ne quitte jamais vraiment la machine
  4. Le système d'exploitation fait « rebondir » le paquet via l'interface de boucle locale (loopback interface)
  5. Le programme qui écoute sur le port 3000 reçoit la requête et renvoie la réponse

Tout le processus ne passe par aucun câble réseau, aucun routeur et ne nécessite aucune connexion Internet.

👇 Essayez par vous-même : Cliquez sur « Envoyer la requête » pour observer le parcours complet du paquet de données. Cliquez ensuite sur les « cartes alias » ci-dessous pour découvrir les différentes écritures de localhost et leurs différences.

🔗
🌐
BrowserYou enter URL in address bar
📖
DNS Resolutionlocalhost → 127.0.0.1 (no internet)
🔄
Network LayerPacket sent to 127.0.0.1 (loopback interface)
⚙️
Local ServiceProgram on port 3000 receives request
📨
Return Response{ "message": "Hello!" }
Your App(Browser)
Request stays on local machine
Local Service(:3000)
Localhost "Aliases" (click to see description)
localhost→ 127.0.0.1
127.0.0.1→ 127.0.0.1
::1→ ::1
0.0.0.0→ 0.0.0.0
This is mapped in your computer's <code>/etc/hosts</code> file. When browser sees <code>localhost</code>, it directly resolves to <code>127.0.0.1</code> without asking DNS server.: 这是写在你电脑 /etc/hosts 文件里的映射。浏览器看到 localhost 时,直接解析为 127.0.0.1,不会去问 DNS 服务器。
Core Concept:localhost 就是"自己找自己"。数据包通过环回接口(loopback interface)在本机内部折返,不经过网线、不经过路由器,速度极快且完全安全。

2.2 localhost vs 127.0.0.1 vs 0.0.0.0

Ces trois concepts sont souvent confondus, mais leurs significations sont complètement différentes :

ÉcritureSignificationQui peut accéder
localhost / 127.0.0.1Adresse de boucle locale, uniquement la machine localeSeulement votre propre ordinateur
0.0.0.0Écoute sur toutes les interfaces réseauMachine locale + autres appareils du réseau local
192.168.x.xIP du réseau localAppareils du réseau local

Scénarios pratiques :

bash
# Seul vous-même pouvez accéder (sécurisé, adapté au développement)
npm run dev -- --host localhost

# Le téléphone peut aussi accéder (adapté au débogage mobile)
npm run dev -- --host 0.0.0.0

De nombreux frameworks (comme Vite, Next.js) écoutent par défaut sur localhost, donc votre téléphone ne peut pas accéder même connecté au même WiFi. Vous voulez déboguer sur mobile ? Ajoutez le paramètre --host.


3. Conflit de ports : le problème le plus courant en environnement de développement

3.1 Pourquoi y a-t-il conflit ?

Un port ne peut être écouté que par un seul programme à la fois. C'est comme un appartement qui ne peut être occupé que par une seule famille.

Si vous essayez de démarrer un deuxième service sur le même port, vous verrez cette erreur classique :

Error: listen EADDRINUSE :::3000

Traduit en langage humain : « L'appartement n°3000 est déjà occupé, vous ne pouvez pas entrer ! »

Scénarios de conflit courants :

  • Le serveur de développement précédent n'a pas été correctement arrêté et tourne encore en arrière-plan
  • Deux projets différents utilisent le même port par défaut
  • Un service système occupe déjà le port que vous voulez utiliser

👇 Essayez par vous-même : Essayez de démarrer plusieurs fois le service dans le simulateur ci-dessous. En cas de conflit de port, comparez les différentes approches entre le « démarrage direct » et le « démarrage intelligent ».

Try starting:React(default port 5173)
Currently Running Services1 services
Vite:5173🟢 Running
Port Conflict:一个端口同一时刻只能被一个程序监听。如果你看到 EADDRINUSE 错误,说明这个端口已经被占了。要么杀掉旧进程,要么换个端口。

3.2 Diagnostic et résolution

Face à un conflit de port, la procédure de diagnostic est très standardisée :

macOS / Linux :

bash
# Étape 1 : voir qui occupe le port 3000
lsof -i :3000

# Étape 2 : une fois le PID obtenu, forcer l'arrêt
kill -9 <PID>

Windows :

bash
# Étape 1 : voir qui occupe le port 3000
netstat -ano | findstr :3000

# Étape 2 : terminer le processus
taskkill /PID <PID> /F

De nombreux frameworks modernes (Vite, Create React App, etc.) demandent automatiquement « Voulez-vous changer de port ? » en cas de conflit. Mais comprendre le principe sous-jacent vous aide à diagnostiquer plus rapidement les problèmes complexes que les frameworks ne peuvent pas résoudre pour vous.


4. La « Same-Origin Policy » et le cross-origin en développement

4.1 Qu'est-ce qu'une « origine » ?

Le navigateur a un mécanisme de sécurité appelé Same-Origin Policy (politique de même origine) : seules les ressources ayant exactement le même protocole, nom de domaine et port sont considérées comme de « même origine ».

Adresse AAdresse BMême origine ?Raison
http://localhost:5173http://localhost:5173/about✅ Même origineProtocole, domaine et port identiques
http://localhost:5173http://localhost:3000❌ Origine différentePort différent (5173 vs 3000)
http://localhost:5173https://localhost:5173❌ Origine différenteProtocole différent (http vs https)

4.2 Pourquoi la séparation frontend/backend rencontre-t-elle forcément le cross-origin ?

Quand l'architecture de votre projet est :

Frontend (Vite)   →  http://localhost:5173
Backend (Express) →  http://localhost:3000

La page frontend est chargée depuis :5173, puis utilise fetch('/api/users') pour appeler l'API sur :3000les ports sont différents, la restriction cross-origin se déclenche !

Deux solutions courantes :

Solution 1 : configurer CORS côté backend

javascript
// Backend Express
app.use(cors({ origin: 'http://localhost:5173' }))

Solution 2 : configurer un proxy côté frontend (recommandé)

javascript
// vite.config.js
export default {
  server: {
    proxy: {
      '/api': 'http://localhost:3000'
    }
  }
}

Le principe du proxy : laisser le serveur de développement Vite « transférer » les requêtes pour vous. Le navigateur croit communiquer avec :5173 (même origine), mais en réalité Vite transmet discrètement la requête à :3000 en coulisses.


5. Diagnostic pratique : les trois problèmes les plus fréquents

👇 Essayez par vous-même : Choisissez un problème que vous avez déjà rencontré et suivez les étapes de diagnostic. Vous pouvez cliquer sur « Exécuter » à chaque étape pour voir le résultat.

Select a common issue:
🔴
Port OccupiedError: listen EADDRINUSE :::3000
Troubleshooting Steps (1/3)
$lsof -i :3000
Check who is using this port
Troubleshooting Mantra:先确认服务有没有启动(lsof / netstat),再确认端口对不对,最后确认是不是跨域问题。90% 的 localhost 问题都逃不出这三步。

6. Glossaire

Terme anglaisCorrespondanceExplication
PortPortUn nombre entre 0 et 65535, utilisé pour distinguer les différents services réseau sur une même machine. Chaque service « écoute » un port, en attente de connexions client.
localhostHôte localUn nom de domaine spécial, pointant toujours vers la machine locale (127.0.0.1). Utilisé pour accéder aux services exécutés sur la machine locale sans connexion réseau.
Loopback InterfaceInterface de boucle localeInterface réseau virtuelle du système d'exploitation. Les paquets envoyés à 127.0.0.1 ne quittent pas la machine mais sont « renvoyés » via cette interface.
EADDRINUSEAdresse déjà utiliséeErreur signalée par Node.js / le système d'exploitation, indiquant que le port que vous voulez écouter est déjà occupé par un autre programme.
CORSPartage de ressources cross-originMécanisme de sécurité du navigateur. Quand une page frontend tente d'appeler une API d'une origine différente (protocole/domaine/port différents), le backend doit donner une autorisation explicite.
Same-Origin PolicyPolitique de même originePierre angulaire de la sécurité du navigateur : seules les requêtes de même protocole, même domaine et même port peuvent communiquer librement, bloquant la lecture de données cross-origin.
ProxyProxyEn environnement de développement, le serveur proxy transfère les requêtes au backend à la place du navigateur, contournant les restrictions de même origine du navigateur.
0.0.0.0Toutes les interfacesQuand un service écoute sur 0.0.0.0, il accepte les connexions provenant de n'importe quelle interface réseau (machine locale, réseau local, etc.).
Well-known PortsPorts bien connusTerme collectif pour les ports 0-1023, réservés aux protocoles standards comme HTTP (80), HTTPS (443), SSH (22).
PIDID de processusNuméro unique attribué par le système d'exploitation à chaque programme en cours d'exécution, utilisé pour gérer et terminer les processus.
lsofLister les fichiers ouvertsCommande macOS/Linux pour voir quel processus occupe un port donné (lsof -i :numéro_port).
HMRHot Module ReplacementFonctionnalité du serveur de développement : quand vous modifiez le code, le navigateur se met à jour automatiquement sans rafraîchissement manuel. Le mécanisme sous-jacent utilise WebSocket pour notifier le navigateur.

Résumé

Les ports et localhost sont les concepts les plus fondamentaux et les plus fréquents en environnement de développement :

  • Port = le « numéro d'appartement » qui distingue les différents services sur une machine (0-65535)
  • localhost = l'adresse spéciale « se chercher soi-même » (127.0.0.1), les données ne quittent pas la machine
  • La nature du conflit de port est qu'« une seule plaque peut être accrochée à une porte »
  • La nature du cross-origin est que « port différent = origine différente », nécessitant CORS ou un proxy pour résoudre

Retenez ces quatre phrases, et vous pourrez rapidement identifier la cause de la plupart des problèmes réseau que vous rencontrez en environnement de développement.