Python中nginx+django+gunicorn遇到URL空格转义问题如何解决?

URL 如果是 123 456,浏览器点击后就会变成 123%20456
在 django 自带的调试服务中,通过 URL 正则获取到的值是 123 456,一点问题没有

但通过 nginx+django+gunicorn 部署到生产服务器,获取到的值是 123%20456,然后导致与数据库交互有一些错误,但感觉也不是 django 的 bug 啊~难道是 nginx+gunicorn 的问题?我是通过 proxy_pass 传递数据的~
Python中nginx+django+gunicorn遇到URL空格转义问题如何解决?

3 回复

这个问题我遇到过,是nginx和gunicorn对URL编码处理不一致导致的。

nginx默认会对URL中的空格进行转义,但gunicorn可能不会正确处理这些转义字符。解决方案是在nginx配置中添加proxy_pass指令时进行URL解码处理。

修改你的nginx配置文件(通常是/etc/nginx/sites-available/your-site):

location / {
    # 关键配置:禁用nginx的URL重写,保持原始URL
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    
    # 这里是最重要的部分
    proxy_pass http://unix:/path/to/your/gunicorn.sock;
    
    # 如果需要处理更复杂的URL编码问题,可以添加:
    proxy_set_header X-Original-URI $request_uri;
}

同时确保Django的settings.py中配置了正确的中间件:

# settings.py
MIDDLEWARE = [
    'django.middleware.common.CommonMiddleware',  # 这个中间件会处理URL规范化
    # ... 其他中间件
]

# 如果需要更严格的控制,可以设置:
APPEND_SLASH = False  # 防止自动添加斜杠导致的URL变化

如果问题依然存在,可以在Django视图层手动处理:

from urllib.parse import unquote

def your_view(request):
    # 手动解码URL参数
    original_path = unquote(request.path)
    query_string = unquote(request.META.get('QUERY_STRING', ''))
    # ... 处理逻辑

总结:主要调整nginx配置保持URL原样传递。


注意你的 url 里面 123 和 456 的空格,应该是空格 urlencode 转换成了%20

已经找到解决办法了,我把 gunicorn 的 worker 由 aiohttp 换成 gevent 就好了~估计是 aiohttp 的锅

回到顶部