localhost vs 127.0.0.1
Every web developer is familiar with
localhost. It's what you see when you run
npm run dev or similar commands to start a local HTTP server. You might also know that
127.0.0.1 is the IP address of localhost. But what's the difference, and why might you encounter
Connection refused when trying to reach your localhost by IP? This post will shed light on these questions.
In a network, each device can be identified by an IP address. The IP address
127.0.0.1 belongs to a virtual network interface. This special interface represents the device itself and is only accessible to programs running on this device.
localhost is a hostname, which is a human-friendly representation of a device in a network.
Like any other hostname or domain, this text should be resolved into an IP address. When you open any domain in a browser, the browser retrieves one or more IP addresses associated with that domain.
localhost typically corresponds to two IP addresses:
127.0.0.1- the well-known IPv4 address (IP address version 4).
[::1]- the newer IPv6 address (IP address version 6).
You might encounter this issue when testing API, for instance.
Let's delve into why
http://localhost:3000 works perfectly in the browser, but
http://127.0.0.1:3000 doesn't. To illustrate, start web app in the console:
$ npm run dev Nuxt 3.7.4 with Nitro 2.6.3 ➜ Local: http://localhost:3000/ ➜ Network: use --host to expose
Make request with
curl in the console:
$ curl -v 'http://127.0.0.1:3000/' * Trying 127.0.0.1:3000... * connect to 127.0.0.1 port 3000 failed: Connection refused ...
As we learned earlier,
localhost stands for
127.0.0.1, but direct request fails. This happens because the
dev server is bound to the IPv6 address
[::1]. Make the same request, but to the IPv6 address:
$ curl -v 'http://[::1]:3000/' * Trying [::1]:3000... * Connected to ::1 (::1) port 3000 (#0)
There you have it. Finally, let's see what happens when we use the hostname:
$ curl -v 'http://localhost:3000/' curl -v 'http://localhost:3000/' * Trying 127.0.0.1:3000... * connect to 127.0.0.1 port 3000 failed: Connection refused * Trying [::1]:3000... * Connected to localhost (::1) port 3000 (#0)
localhost is resolved into two addresses, and
curl tries both.
In light of this, there are two potential solutions. The first is to consistently use
localhost wherever your dev server's address is required, such as in testing tools, scripts, and so on.
The second solution is to configure your web application to start the dev server on
127.0.0.1. In this case, localhost will continue to work as well.
By understanding the difference between localhost and 127.0.0.1, and knowing how to handle potential connection issues, you can ensure a smoother development process.