关于django路由被意外重定向的问题

问题描述:开发项目 前端antd pro,后端django。在本地进行开发时,路由一切正常,但是将其部署到服务器后,有几个url不能正常访问。

一个斜杠引发的血案

 

由于前端的请求需要经过uwsgi转发到后台django,首先查看uwsgi日志,发现如下记录:

[pid: 9313|app: 0|req: 2/2] 127.0.0.1 () {48 vars in 913 bytes} [Tue Jul  2 14:38:20 2019]     GET /get_user_list => generated 0 bytes in 1 msecs (HTTP/1.0 301) 3 headers in 120 bytes (1     switches on core 0)

主要注意(HTTP/1.0 301),说明该请求被重定向了。

最后经过分析,发现请求在经过真正的后台路由之前,会经过一系列的django中间件处理,如果其中有什么错误的话,该请求就会被重定向。

 

修改中间件源码(主要是输出一些调试信息),主要是中间件的process_request(self, request)函数。最后发现,在最后面决定是否重定向的时候,path与request.get_full_path()之间相差一个斜杠,从而导致了重定向。。。。

def process_request(self, request):
        """
        Check for denied User-Agents and rewrite the URL based on
        settings.APPEND_SLASH and settings.PREPEND_WWW
        """

        # Check for denied User-Agents
        if 'HTTP_USER_AGENT' in request.META:
            for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
                if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
                    raise PermissionDenied('Forbidden user agent')

        # Check for a redirect based on settings.PREPEND_WWW
        host = request.get_host()
        must_prepend = settings.PREPEND_WWW and host and not host.startswith('www.')
        redirect_url = ('%s://www.%s' % (request.scheme, host)) if must_prepend else ''

        # Check if a slash should be appended
        if self.should_redirect_with_slash(request):
            path = self.get_full_path_with_slash(request)
        else:
            path = request.get_full_path()

        # Return a redirect if necessary
        if redirect_url or path != request.get_full_path():
            redirect_url += path
            return self.response_redirect_class(redirect_url)

 

为什么在本地进行开发时没有错误呢???

因为本地使用的django1.8,而服务器上使用的是django1.11.20,它们中间件的代码不一样,从而引发了关于一条斜杠的惨案。

在django1.8中,访问/xxx会被重定向到/xxx/上,而1.11版本则也会重定向到/xxx/,但返回的却是空。

1.8:

[02/Jul/2019 17:42:15]"GET /get_user_list?offset=0&limit=15 HTTP/1.1" 301 0
[02/Jul/2019 17:42:16]"GET /get_user_list/?offset=0&limit=15 HTTP/1.1" 200 1344

1.11

[pid: 15633|app: 0|req: 5/5] 127.0.0.1 () {48 vars in 913 bytes} [Tue Jul  2 18:04:10 2019] GET /get_user_list => generated 0 bytes in 0 msecs (HTTP/1.0 301) 5 headers in 163 bytes (1 switches on core 0)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Django)