我有一个Django项目,其中有一个名为"Surveys"-希望url如http://example.com/Surveys/ViewInspection/1可以通过http://example.com/Inspections/ViewInspection/1访问。
使用Apache 2.4和mod_rewrite,我有以下一组规则来允许这样做:
RewriteEngine On
RewriteRule ^/Inspections(.+)$ /Surveys$1 [PT]
和所有这些似乎都可以正常工作,除了未经身份验证的用户试图访问上述URL(该视图具有@login_required装饰器)。
此时,用户被跳转到带有参数的登录屏幕:/Auth/Login?next=/Ins/Surveys/ViewInspection/1
经过一番挖掘,"/Ins/Surveys/viewininspection/1"是请求的值。路径,而请求。path_info被正确地设置为/Surveys/ViewInspection/1 - Auth代码正在使用.path并得到它错误。如果我使用比"Inspections"更短的字符串Ins部分减少直到消失,这时一切正常。
mod_rewrite日志在这个例子中看起来是正确的:
[Tue Feb 23 23:52:49.617840 2021] [rewrite:trace2] [pid 2760:tid 140156097316608] mod_rewrite.c(483): [client 213.18.147.204:4054] 213.18.147.204 - - [hostname/sid#7f78a4651338][rid#7f78a53910a0/initial] init rewrite engine with requested uri /Inspections/ViewInspection/2
[Tue Feb 23 23:52:49.617906 2021] [rewrite:trace3] [pid 2760:tid 140156097316608] mod_rewrite.c(483): [client 213.18.147.204:4054] 213.18.147.204 - - [hostname/sid#7f78a4651338][rid#7f78a53910a0/initial] applying pattern '^/Inspections(.+)$' to uri '/Inspections/ViewInspection/2'
[Tue Feb 23 23:52:49.617940 2021] [rewrite:trace2] [pid 2760:tid 140156097316608] mod_rewrite.c(483): [client 213.18.147.204:4054] 213.18.147.204 - - [hostname/sid#7f78a4651338][rid#7f78a53910a0/initial] rewrite '/Inspections/ViewInspection/2' -> '/Surveys/ViewInspection/2'
[Tue Feb 23 23:52:49.617956 2021] [rewrite:trace2] [pid 2760:tid 140156097316608] mod_rewrite.c(483): [client 213.18.147.204:4054] 213.18.147.204 - - [hostname/sid#7f78a4651338][rid#7f78a53910a0/initial] forcing '/Surveys/ViewInspection/2' to get passed through to next API URI-to-filename handler
[Tue Feb 23 23:52:49.618103 2021] [rewrite:trace2] [pid 2760:tid 140156097316608] mod_rewrite.c(483): [client 213.18.147.204:4054] 213.18.147.204 - - [hostname/sid#7f78a4651338][rid#7f78a54060a0/subreq] init rewrite engine with requested uri /Surveys/ViewInspection/2
[Tue Feb 23 23:52:49.618119 2021] [rewrite:trace3] [pid 2760:tid 140156097316608] mod_rewrite.c(483): [client 213.18.147.204:4054] 213.18.147.204 - - [hostname/sid#7f78a4651338][rid#7f78a54060a0/subreq] applying pattern '^/Inspections(.+)$' to uri '/Surveys/ViewInspection/2'
[Tue Feb 23 23:52:49.618131 2021] [rewrite:trace1] [pid 2760:tid 140156097316608] mod_rewrite.c(483): [client 213.18.147.204:4054] 213.18.147.204 - - [hostname/sid#7f78a4651338][rid#7f78a54060a0/subreq] pass through /Surveys/ViewInspection/2
知道我在这里做错了什么导致请求吗?路径是错误的,混淆了登录后的重定向?
如果我缩短"Inspections"在重写规则中,它相应地缩短了"Ins"部分不正确的请求。路径-所以一个简短的(<8字符)字符串可以使一切工作完美。我实在看不出这是怎么回事。
在添加WSGI中间件以将WSGI信息删除到Apache错误日志后,我在django.core.handlers.wsgi.py
中的第177行找到了罪魁祸首。if script_url:
if b'//' in script_url:
# mod_wsgi squashes multiple successive slashes in PATH_INFO,
# do the same with script_url before manipulating paths (#17133).
script_url = _slashes_re.sub(b'/', script_url)
path_info = get_bytes_from_wsgi(environ, 'PATH_INFO', '')
script_name = script_url[:-len(path_info)] if path_info else script_url
else:
script_name = get_bytes_from_wsgi(environ, 'SCRIPT_NAME', '')
在这里,我们在这一小段代码中结束,因为script_name是来自mod_wsgi的零字符串(我不在子目录中)。path_info
被Apache设置为/Surveys/ViewInspection/1
(正确,从mod_rewrite);script_url
是/Inspections/ViewInspection/1
(再次正确- pre- mod_rewrite URL)。
代码script_url[:-len(path_info)]
盲目地去掉了path_info作为脚本名的长度,这是错误的。
FORCE_SCRIPT_NAME = ""
到Django settings.py文件。