URL能写多长
事情背景
开发同学要上一个新功能,会使用GET方式带很长的一对参数过来,问这块URL能支持多长的字符,一下问倒我了,平时没有留意过这块。
Google一下
Google了一下这块,借URL最大长度限制探究作者的图上结论:

URL长度和请求头大小不应该超过8KB,8KB是什么概念呢?1KB=1024Byte(字节),8KB就是8192字节。
一般来说,英文状态下一个字母或数字(称之为字符)占用一个字节,一个汉字用两个字节表示。在不同的编码方式下一个字符占的字节不太一样。 按照ANSI编码标准,标点符号、数字、大小写字母都占一个字节,汉字占2个字节。按照UNICODE标准所有字符都占2个字节。
8192个字符对业务来说足够了,如果在浏览器里面输入呢?了解跨浏览器的最大-url-长度 参考这篇文章,和上面那篇的结论一样,Chrome就是2MB,https://github.com/chromium/chromium/blob/main/url/url_constants.h 里面定义了
inline constexpr size_t kMaxURLChars = 2 * 1024 * 1024;
测试验证
用测试服务的域名进行下测试,直接带了1W个字符”a”,直接返回了500异常,跳转到了默认的50x.html页面,如下图:


上来就打脸了,打开域名所在Nginx的Error debug日志看一下

尽然是hmux_header_packet_buffer_size 太大了,其实也赶巧了,刚好测试的是一个老服务,走的还是resin的那套hmux协议,不是http协议

hmux_header_packet_buffer_size模块中默认是8KB,1W个”a”肯定是超了

修改完hmux_header_packet_buffer_size后请求就变正常了,但是后端返回了400错误,问了下开发,服务后端默认接收的最大字符数是不能超过8192的。

不用Nginx,直接用Python测试
#server
from flask import Flask
app = Flask(__name__)
@app.errorhandler(400)
def bad_request(e):
return 'HTTP/1.1 400 Bad Request\r\n\r\n', 400
@app.route('/search')
def hello_world():
return '<h1>Hello World</h1>', 200
if __name__ == '__main__':
app.run(debug=False , host='127.0.0.1', port=9090)
#client
import requests
def check_url_length(url):
try:
response = requests.get(url)
print(response.status_code)
return response.status_code == 200
except requests.exceptions.RequestException:
return False
urls = [
'http://127.0.0.1:9090/search?result=' + 'a' * 1000,
'http://127.0.0.1:9090/search?result=' + 'a' * 2000,
'http://127.0.0.1:9090/search?result=' + 'a' * 5000,
'http://127.0.0.1:9090/search?result=' + 'a' * 10240,
'http://127.0.0.1:9090/search?result=' + 'a' * 1024 * 1024
]
for url in urls:
print(len(url), check_url_length(url))

1024*1024的时候就提示414了,flask HTTP框架也限制了GET传过来的字符数量。

写在最后
URL长度的限制在浏览器、Nginx|Apache、后端服务都有限制,建议不超过8KB,太长的放到POST中去处理。
祝大家中秋节快乐!~