zoukankan      html  css  js  c++  java
  • Django获取用户请求头部信息

    摘要

    在我们的Django开发中,有时候会需要用到用户请求头部信息。列举几个简单的例子:

    • 获取用户客户端类型HTTP_USER_AGENT
    • 获取用户的出口IPREMOTE_ADDR
    • 获取用户HTTP方式REQUEST_METHOD

    但是如何在Django中获取这些信息呢?

    从请求入手
    1. Django的请求生命周期

    • 用户发出请求,浏览器封装请求头和请求体发给服务端
    • 请求经过Django中的wsgi,到达url关系映射表进行匹配
    • 只要匹配上其中一条匹配规则就执行对应的视图函数
    • 视图函数根据客户端的请求做相应的处理,并将处理结果(字符串)经由模板加工渲染返回给用户
    • 用户浏览器进行渲染后呈现给用户

    2. request里面到底是什么

    我们在某一个视图函数中打印这个request

    def index(request):
        print(type(request),request)
    

    得到输出如下

    <class 'django.core.handlers.wsgi.WSGIRequest'> <WSGIRequest: GET '/index/'>
    

    可见request是一个类WSGIRequest的对象,这个类在django.core.handlers.wsgi中.

    去查看这个类,如下:

    
    class WSGIRequest(http.HttpRequest):
        def __init__(self, environ):
            script_name = get_script_name(environ)
            path_info = get_path_info(environ)
            if not path_info:
                # Sometimes PATH_INFO exists, but is empty (e.g. accessing
                # the SCRIPT_NAME URL without a trailing slash). We really need to
                # operate as if they'd requested '/'. Not amazingly nice to force
                # the path like this, but should be harmless.
                path_info = '/'
            self.environ = environ
            self.path_info = path_info
            # be careful to only replace the first slash in the path because of
            # http://test/something and http://test//something being different as
            # stated in http://www.ietf.org/rfc/rfc2396.txt
            self.path = '%s/%s' % (script_name.rstrip('/'),
                                   path_info.replace('/', '', 1))
            self.META = environ
            self.META['PATH_INFO'] = path_info
            self.META['SCRIPT_NAME'] = script_name
            self.method = environ['REQUEST_METHOD'].upper()
            self.content_type, self.content_params = cgi.parse_header(environ.get('CONTENT_TYPE', ''))
            if 'charset' in self.content_params:
                try:
                    codecs.lookup(self.content_params['charset'])
                except LookupError:
                    pass
                else:
                    self.encoding = self.content_params['charset']
            self._post_parse_error = False
            try:
                content_length = int(environ.get('CONTENT_LENGTH'))
            except (ValueError, TypeError):
                content_length = 0
            self._stream = LimitedStream(self.environ['wsgi.input'], content_length)
            self._read_started = False
            self.resolver_match = None
    ....
    

    可以看到类中封装了一个属性:

    • self.environ
    • self.path_info
    • self.method
    • self.path
    • ...

    我们依次打印出来这些信息看看:

    
    environ {'PATH': '/Users/qiumeng/.pyenv/versions/3.6.2/bin:/usr/local/Cellar/pyenv/1.1.3/libexec:/Users/qiumeng/.pyenv/shims:/Users/qiumeng/.pyenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Applications/Wireshark.app/Contents/MacOS:/Users/qiumeng/GoLang/bin:/usr/local/Cellar/go/1.8.3/libexec/bin', 'PYENV_SHELL': 'bash', 'DISPLAY': '/private/tmp/com.apple.launchd.5ODiXCCeal/org.macosforge.xquartz:0', 'LOGNAME': 'qiumeng', 'PYENV_VERSION': '3.6.2', 'XPC_SERVICE_NAME': 'com.jetbrains.pycharm.8256', 'PWD': '/Users/qiumeng/PycharmProjects/day21', 'PYCHARM_HOSTED': '1', 'PYTHONPATH': '/Users/qiumeng/PycharmProjects/day21', 'SHELL': '/bin/bash', 'PYTHONIOENCODING': 'UTF-8', 'PYENV_DIR': '/Applications/PyCharm.app/Contents/bin', 'PYENV_ROOT': '/Users/qiumeng/.pyenv', 'GOPATH': '/Users/qiumeng/GoLang', 'USER': 'qiumeng', 'GOROOT': '/usr/local/Cellar/go/1.8.3/libexec', 'TMPDIR': '/var/folders/k5/9fcwbxhn1_d_x3lxvs868m6c0000gn/T/', 'PYENV_HOOK_PATH': '/Users/qiumeng/.pyenv/pyenv.d:/usr/local/Cellar/pyenv/1.1.3/pyenv.d:/usr/local/etc/pyenv.d:/etc/pyenv.d:/usr/lib/pyenv/hooks', 'SSH_AUTH_SOCK': '/private/tmp/com.apple.launchd.kT7ERQ3lJ4/Listeners', 'DJANGO_SETTINGS_MODULE': 'day21.settings', 'XPC_FLAGS': '0x0', 'PYTHONUNBUFFERED': '1', '__CF_USER_TEXT_ENCODING': '0x1F5:0x19:0x34', 'Apple_PubSub_Socket_Render': '/private/tmp/com.apple.launchd.nEfmDxko1b/Render', 'LC_CTYPE': 'zh_CN.UTF-8', 'HOME': '/Users/qiumeng', 'TZ': 'UTC', 'RUN_MAIN': 'true', 'SERVER_NAME': '1.0.0.127.in-addr.arpa', 'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_PORT': '8000', 'REMOTE_HOST': '', 'CONTENT_LENGTH': '', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'WSGIServer/0.2', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/index/', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'CONTENT_TYPE': 'text/plain', 'HTTP_HOST': '127.0.0.1:8000', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_CACHE_CONTROL': 'max-age=0', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'HTTP_COOKIE': 'csrftoken=Ne1RJ3duPUV5mFJysr9r48fgEZCaJY75RFsh6ujbELqQYYzxOynhoLSVT3GnUblx', 'wsgi.input': <_io.BufferedReader name=4>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 'wsgi.version': (1, 0), 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>}
    
    path_info /index/
    method GET
    path /index/
    
    
    3. environ属性

    从上面的environ中我们看到,我们想要的任何存在的请求头信息是在environ
    这个属性中的,我们把它一一列举一下:

    def index(request):
        print(type(request.environ))
        for k,v in request.environ.items():
            print(k,v)
    

    结果如下:

    PATH /Users/qiumeng/.pyenv/versions/3.6.2/bin:/usr/local/Cellar/pyenv/1.1.3/libexec:/Users/qiumeng/.pyenv/shims:/Users/qiumeng/.pyenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Applications/Wireshark.app/Contents/MacOS:/Users/qiumeng/GoLang/bin:/usr/local/Cellar/go/1.8.3/libexec/bin
    PYENV_SHELL bash
    DISPLAY /private/tmp/com.apple.launchd.5ODiXCCeal/org.macosforge.xquartz:0
    LOGNAME qiumeng
    PYENV_VERSION 3.6.2
    XPC_SERVICE_NAME com.jetbrains.pycharm.8256
    PWD /Users/qiumeng/PycharmProjects/day21
    PYCHARM_HOSTED 1
    PYTHONPATH /Users/qiumeng/PycharmProjects/day21
    SHELL /bin/bash
    PYTHONIOENCODING UTF-8
    PYENV_DIR /Applications/PyCharm.app/Contents/bin
    PYENV_ROOT /Users/qiumeng/.pyenv
    GOPATH /Users/qiumeng/GoLang
    USER qiumeng
    GOROOT /usr/local/Cellar/go/1.8.3/libexec
    TMPDIR /var/folders/k5/9fcwbxhn1_d_x3lxvs868m6c0000gn/T/
    PYENV_HOOK_PATH /Users/qiumeng/.pyenv/pyenv.d:/usr/local/Cellar/pyenv/1.1.3/pyenv.d:/usr/local/etc/pyenv.d:/etc/pyenv.d:/usr/lib/pyenv/hooks
    SSH_AUTH_SOCK /private/tmp/com.apple.launchd.kT7ERQ3lJ4/Listeners
    DJANGO_SETTINGS_MODULE day21.settings
    XPC_FLAGS 0x0
    PYTHONUNBUFFERED 1
    __CF_USER_TEXT_ENCODING 0x1F5:0x19:0x34
    Apple_PubSub_Socket_Render /private/tmp/com.apple.launchd.nEfmDxko1b/Render
    LC_CTYPE zh_CN.UTF-8
    HOME /Users/qiumeng
    TZ UTC
    RUN_MAIN true
    SERVER_NAME 1.0.0.127.in-addr.arpa
    GATEWAY_INTERFACE CGI/1.1
    SERVER_PORT 8000
    REMOTE_HOST 
    CONTENT_LENGTH 
    SCRIPT_NAME 
    SERVER_PROTOCOL HTTP/1.1
    SERVER_SOFTWARE WSGIServer/0.2
    REQUEST_METHOD GET
    PATH_INFO /index/
    QUERY_STRING 
    REMOTE_ADDR 127.0.0.1
    CONTENT_TYPE text/plain
    HTTP_HOST 127.0.0.1:8000
    HTTP_CONNECTION keep-alive
    HTTP_CACHE_CONTROL max-age=0
    HTTP_USER_AGENT Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36
    HTTP_UPGRADE_INSECURE_REQUESTS 1
    HTTP_ACCEPT text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    HTTP_ACCEPT_ENCODING gzip, deflate, br
    HTTP_ACCEPT_LANGUAGE zh-CN,zh;q=0.9
    HTTP_COOKIE csrftoken=Ne1RJ3duPUV5mFJysr9r48fgEZCaJY75RFsh6ujbELqQYYzxOynhoLSVT3GnUblx
    wsgi.input <_io.BufferedReader name=5>
    wsgi.errors <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>
    wsgi.version (1, 0)
    wsgi.run_once False
    wsgi.url_scheme http
    wsgi.multithread True
    wsgi.multiprocess False
    wsgi.file_wrapper <class 'wsgiref.util.FileWrapper'>
    
  • 相关阅读:
    phpcms后台进入地址(包含No permission resources错误)
    phpmyadmin上传大sql文件办法
    ubuntu彻底卸载mysql
    Hdoj 2602.Bone Collector 题解
    一篇看懂词向量
    Hdoj 1905.Pseudoprime numbers 题解
    The Python Challenge 谜题全解(持续更新)
    Hdoj 2289.Cup 题解
    Hdoj 2899.Strange fuction 题解
    Hdoj 2199.Can you solve this equation? 题解
  • 原文地址:https://www.cnblogs.com/forsaken627/p/12521980.html
Copyright © 2011-2022 走看看