如果你用 macOS 开发 Flask 时无法正常访问程序,或是使用 ngrok 等内网穿透工具时映射的公网地址无法访问,大概率是因为 macOS 新版本(Monterey)的变动导致。你会在页面上看到类似下面的错误信息:
Access to 127.0.0.1 was denied.
You don't have authorization to view this page.
HTTP ERROR 403
或是在执行 flask run 命令时看到类似下面的报错:
OSError: [Errno 48] Address already in use
首先确认你的 macOS 版本是不是 Monterey(左上角 Apple 图标 – About This Mac)或是之后的版本,如果不是那么问题应该和本文无关。
简单来说,新版本的 macOS 上 localhost 5000 端口被一个叫 AirPlay Receiver 的服务占用了。而 Flask 内置服务器默认就运行在 5000 端口,所以会造成端口冲突。当你通过将 host 设为 0.0.0.0 指定 Flask 的内置服务器对外可见,或是使用内网穿透工具时,会发现程序无法访问(有时未设置对外可见也会遇到这个问题)。
最简单的解决方法是关掉这个服务:
- 系统设置(System Preferences) > 分享(Sharing) > AirPlay Receiver > 取消勾选
或是更改 Flask 开发服务器默认的端口(比如改成 8000)。在执行 flask run 命令时使用 -p/–port 选项可以自定义端口:
$ flask run -p 8000 # 或 flask run --port 8000
或是在执行 flask run 之前通过环境变量 FLASK_RUN_PORT 设置:
$ export FLASK_RUN_PORT=8000 # macOS/Linux
> set FLASK_RUN_PORT=8000 # Windows CMD
> $env:FLASK_RUN_PORT=8000 # Powershell
在 Werkzueg 2.1.0(2022/3/28 发布)版本,如果你执行 flask run –host=0.0.0.0 时检测到了端口被占用,会直接显示相关的错误提示:
$ flask run --host=0.0.0.0
Address already in use
Port 5000 is in use by another program. Either identify and stop that program, or start the server with a different port.
On macOS, try disabling the 'AirPlay Receiver' service from System Preferences -> Sharing.
本文源于去年十一月发的一条推文,最近经常碰见有人遇到这个问题,所以转成这篇文章发出来。
画了一幅涂鸦,送给苹果公司: