刚刚发现一个有趣的现象,测试 django
项目的时候,这样启动服务器:
$ python3 ./manage.py runserver
...
Starting development server at http://127.0.0.1:8000/
...
然后想起 laravel
项目也是 8000
端口,就同时启动 laravel
项目:
$ php artisan serve
Laravel development server started on http://localhost:8000/
问题来了,2 个端口一样,按理说应该会冲突啊,可是没有,打开浏览器,输入 127.0.0.1:8000
,看到的是django
的项目。那么 laravel
项目哪去了,难道没启动成功,可是又没报错?
仔细看 laravel
的输出信息,于是浏览器输入 localhost:8000
,果然,是laravel
的项目,也就是说,127.0.0.1 != localhost?这不可能吧。
于是我用 netstat
看一下,到底是什么情况。
$ netstat -apn | grep 8000
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN 5374/python3
tcp6 0 0 ::1:8000 :::* LISTEN 5518/php7.0
从输出信息看,确实都是 8000
端口,但是地址没发生冲突,也就是说 django
项目默认是用 ipv4
的127.0.0.1
地址,laravel
项目默认用的是 ipv6
地址::1
,地址不一样,那么端口相同也可以。
然后我关掉这 2 个项目,单独启动 laravel
项目,发现默认用的就是 ipv6
地址,也就是说不能用 127.0.0.1
来访问,可以考虑用这 2 个地址访问:
- http://localhost:8000/
- http://[::1]:8000/
看了下 wiki
上的 Localhost 介绍,操作系统的 hosts
文件中的 localhost
解析一些ip
:
127.0.0.1 localhost
::1 localhost
那么问题来了,解析 localhost
是不是有个优先级问题呢?我发现当 laravel
项目启动的时候,默认是解析成 ipv6
的地址 ::1
,而 只开启 django
项目的时候,才会解析成 ipv4
的地址127.0.0.1
。
考虑到其他框架可能会占用 8000
端口,那么有可能 laravel
采用了默认利用 ipv6
地址,从而避免启动端口冲突问题;然而 localhost
先解析ipv6
,从而避免访问冲突问题,真是机智。。。
所以需要用这种方式对 laravel
项目做端口映射就要注意了,用 --hosts
参数指定ip
,例如:
$ php artisan serve --host=127.0.0.1
那么 dns
是否会优先解析 ipv6
呢?我猜应该是的,因为 ipv6
正在慢慢普及。