我是用Flask.app.run()直接运行了服务。效果大概类似这样:
一言以蔽之:用HTTPS协议访问HTTP服务导致的,如果是在浏览器请求的话,把网址里的https
改成http
就好了。
我一开始以为是中文显示问题,以为是终端中文显示乱码,然后我一运行git log
发现,嗯这中文信息不是显示得很流畅吗?……
其实这就是请求的HTTP版本无效,是Flask服务器运行在HTTP模式,但客户端试图用HTTPS访问。
HTTP请求的第一行通常是方法、路径和协议版本,正常请求的长这样:
但收到的却是一个\x16
开头的TLS(传输层安全协议)/SSL握手请求。(\x16
代表TLS Client Hello消息(包含加密算法、随机数、会话 ID 等信息),属于 SSL/TLS 握手过程的第一步)
\x16\x03\x01
开头的数据(这个就是不可打印字符的转义序列,比如十六进制的16(十进制22)、3、1),就说明客户端错误地以 HTTPS 方式连接了 HTTP 端口。具体来说,0x16
表示这是一个握手记录,0x03 0x01
代表TLS 1.0版本。接下来的字节可能对应握手过程的各个部分,比如客户端Hello消息。这些数据对于HTTP服务器来说是无法理解的,因为HTTP服务器期待的是像"GET / HTTP/1.1"这样的文本请求,而不是二进制TLS数据。
通常,HTTPS会在TCP连接建立后进行SSL/TLS握手,而HTTP则是直接发送明文请求。如果客户端错误地将HTTPS请求发送到HTTP端口(比如80端口),服务器会接收到SSL/TLS的二进制数据,而非HTTP明文请求,从而导致解析失败。
当服务器收到不符合预期的请求版本时,会返回400错误。
用户看到的乱码字符是服务器尝试将接收到的原始字节按照某种编码(比如UTF-8)解码后的结果。例如,如果原始字节是二进制数据,用UTF-8解码可能会产生这些奇怪的符号。
à
对应的UTF-8编码是0xC3 0xA0
,ISO-8859-1 中是0xE0
,是另一种错误协议导致的乱码格式。核心问题仍是数据本身为二进制。
HTTP/0.9是非常古老的协议版本,现在几乎不再使用。现代服务器通常支持HTTP/1.0或更高版本。HTTP/0.9的请求格式非常简单,比如“GET /path\r\n”(METHOD PATH),没有版本号、头部等。
出现这个报错信息是因为服务器在解析时发现请求不符合任何已知的HTTP版本,从而回退到HTTP/0.9的处理方式,但依然无法正确解析,因此报错。