Docker环境下Django+Gunicorn+Nginx非ASCII文件名文件404问题
问题描述
在Docker环境下运行Django+Gunicorn+Nginx应用时,使用X-Accel-Redirect头提供受保护文件出现异常:仅含ASCII字符的文件名可正常访问,带非ASCII字符的文件(如książka.pdf)会返回404错误,且已确认文件存在于媒体目录中。通过浏览器开发者工具可见,请求路径从/media/książka.pdf被转换为/media/ksi%C4%85%C5%BCka.pdf。
相关配置如下:
Nginx配置(nginx.conf)
charset utf-8; location /protected_media/ { alias /var/media/; internal; }
Django视图配置(views.py)
@login_required def protected_serve(request, path): response = HttpResponse() response['Content-Type']="" response['X-Accel-Redirect'] = '/protected_media/' + path return response
解决方法
问题核心是URL编码后的路径与Nginx服务器上的实际文件名编码不匹配:浏览器发送的是URL编码后的路径,但Django直接将编码后的path拼接到X-Accel-Redirect中,而Nginx需要与系统文件名一致的UTF-8编码路径。
1. 修改Django视图解码路径
使用urllib.parse.unquote对URL编码的路径进行解码,转换为UTF-8字符串后再拼接:
from urllib.parse import unquote from django.http import HttpResponse from django.contrib.auth.decorators import login_required @login_required def protected_serve(request, path): # 解码URL编码的路径,还原为UTF-8文件名 decoded_path = unquote(path) response = HttpResponse() response['Content-Type'] = "" response['X-Accel-Redirect'] = f'/protected_media/{decoded_path}' return response
2. 验证Nginx与文件系统编码
- 确保Nginx配置中已开启UTF-8支持(现有配置的
charset utf-8;已满足) - 检查Docker容器内文件系统编码为UTF-8,可通过执行
locale命令验证,输出应包含UTF-8 - 确认Django上传文件时已正确保存UTF-8编码的文件名
内容的提问来源于stack exchange,提问作者swgn81
相关产品推荐
相关产品推荐

