IIS部署Django时URL含波斯语字符无法获取路径后缀问题求解
核心问题分析
- IIS默认的请求过滤规则会拦截高比特位字符(非ASCII字符),且FastCGI模块默认不会将原始未处理的URL传递给Django,最终导致Django拿到的
request.path/request.path_info只有/fields/,没有后面的波斯语内容。 - 你之前编写的中间件继承了
WSGIHandler类,这是Django的WSGI请求入口类,不符合Django标准中间件的规范,放在settings.MIDDLEWARE中调用时会出现参数不匹配的报错。
解决方案
1. 调整IIS配置
修改项目根目录下的web.config文件,添加允许非ASCII字符访问、允许传递原始URL的配置:
<system.webServer> <security> <!-- 允许非ASCII字符的URL请求 --> <requestFiltering allowHighBitCharacters="true" /> </security> <rewrite> <allowedServerVariables> <!-- 允许将原始未编码URL传递给后端应用 --> <add name="UNENCODED_URL" /> </allowedServerVariables> <!-- 保留你原有的重写规则不变 --> </rewrite> </system.webServer>
配置完成后重启IIS站点。
2. 编写正确的Django中间件
替换你之前的中间件代码,middleware.py内容如下:
from urllib.parse import unquote from django.http import HttpRequest class IISUnicodeUrlFixMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request: HttpRequest): # 读取IIS传递的原始未处理URL raw_url = request.META.get('UNENCODED_URL', '') if raw_url: # 解码URL编码的内容 decoded_full_url = unquote(raw_url) # 替换request的路径属性,后续视图/路由可以直接使用 request.path = decoded_full_url.split('?')[0] request.path_info = request.path return self.get_response(request)
3. 调整Django配置
修改settings.py中的MIDDLEWARE列表,将上述中间件放在列表最开头,保证在其他中间件处理路径之前完成替换:
MIDDLEWARE = [ 'apps.middleware.IISUnicodeUrlFixMiddleware', # 下方保留你原有所有中间件不变 'django.middleware.security.SecurityMiddleware', ... ]
4. 调整业务代码(可选,提升鲁棒性)
为避免特殊情况出现索引报错,建议调整原有的正则匹配逻辑:
import re from django.http import Http404 # 视图内的代码 match_res = re.search(r'/fields/(.+)', request.path_info) if not match_res: raise Http404 key = match_res.group(1)
完成上述配置后,你就可以在视图中正常拿到URL里的波斯语内容了。
内容的提问来源于stack exchange,提问作者keramat
相关产品推荐
相关产品推荐

