zoukankan      html  css  js  c++  java
  • 解析器

    前提:django 的 request.POST 有值

    • 请求头要求:如果请求头中的 Content-Typeapplication/x-www-form-urlencoded ,才去 request.body 中解析数据
    • 数据格式要求:name=xi&age=18

    form 表单提交默认会按照上面的两种要求进行提交

    ajax 提交中的 data 数据虽然是字典格式,但默认也会把字典转换成上面的数据格式再带上请求头进行提交

    如果 ajax 提交中指定 headers 为 {'Content-Type': 'application/json'},那么 body 有值,POST 无值

    如果 ajax 提交中指定 headers 为 {'Content-Type': 'application/json'},且 data 的数据格式指定为 JSON.stringfy(),那么 body 有值,POST 无值,但是可以到 request.body 中拿到 json 数据,转成字符串类型,然后 json.loads(request.body) 即可获取到字典类型的数据

    rest framework 解析器

    **依靠请求头 content-type 对用户请求体中的数据进行解析,解析到 request.data **

    # demoapiurls
    
    urlpatterns = [
        url(r'^(?P<version>[v1|v2]+)/parser/$', views.ParserView.as_view()),
    ]
    
    # demoapiviews
    
    class ParserView(APIView):
        # 会读取请求头,JSONParser表示只能解析 content-type: application/json 头
        # FormParser表示只能解析 content-type: application/x-www-form-urlencoded 头
        parser_classes = [JSONParser, FormParser, ]
    
        def post(self, request, *args, **kwargs):
            '''
            允许用户发送JSON格式数据
                a. content-type: application/json
                b. {'name':'xi', 'age':18}
            '''
            # 获取解析后的结果,用的时候才去解析,所以是代码的起始位置
            '''
            1. 获取用户的请求
            2. 获取用户的请求体
            3. 根据用户请求头和 parser_classes = [JSONParser, FormParser, ]中支持的请求头进行比较
            4. JSONParser对象去请求体
            5. 赋值给 request.data 作为处理后的结果
            '''
            print(request.data)
            
            return HttpResponse("ParserView")
    

    源码流程

    通过 Request 找到 datadata 中有 _load_data_and_files() ,里面调用了 self._parse()self._parse() 中有 self.content_type

    图片中 344 行,select_parser() 是选择解析器,根据上面用户提交的请求头和所传的 self.parsers 来找,parsers 就是前面 views.py 中所设置的 parser_classes = [JSONParser, FormParser, ]self 是请求相关的所有数据,即请求对象,它里面有一个 contype_type ,是当前用户的 content_type 。根据这两个参数进行选择

    选择好解析器,执行解析器的 parse() 方法,如果选择的是 JSONParser 解析器,就到 JSONParserparse() 方法

    JSONParser 中执行 json.load() 方法,将 json 数据变为字典类型

    上面的内容为源码的一部分,实际上流程的入口其实还是从 dispatch 出发,对 request 进行封装

    def get_parsers(self):
        """
        Instantiates and returns the list of parsers that this view can use.
        """
        # self.parser_classes 读取的还是 APIView 中的设置
        return [parser() for parser in self.parser_classes]
    
    

    所以请求刚进来时,所有 views.py 中所设置的 parser_classes = [JSONParser, FormParser, ] 解析器全部实例化成对象,也封装到 request 中了。目前所学,Request 中有三种东西:封装的 request、认证的所有对象、解析器的所有对象,同样,解析器也可以进行全局配置

    # demodemosettings.py
    
    REST_FRAMEWORK = {
        "DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning",
        "DEFAULT_VERSION": 'v1',
        "ALLOWED_VERSION": ['v1', 'v2'],
        "VERSION_PARAM": 'version',
        "DEFAULT_PARSER_CLASSES": ["rest_framework.parsers.JSONParser", "rest_framework.parsers.FormParser"]
    }
    
    # demoapiviews.py
    
    class ParserView(APIView):
    
        def post(self, request, *args, **kwargs):
            '''
            允许用户发送JSON格式数据
                a. content-type: application/json
                b. {'name':'xi', 'age':18}
            '''
            # 获取解析后的结果
            print(request.data)
            return HttpResponse("ParserView")
    

    总结

    • 使用
      • 全局配置
      • request.data
    • 源码流程
      • dispatch:request 封装
      • request.data
    • 常见的请求头
      • Referer:浏览器向 Web 服务器表明自己是从哪个网页的 URL 获得点击当前请求中的网址
      • User-Agent:浏览器表明自己的身份(是哪种浏览器)
      • Host:客户端指定自己想访问的 Web 服务器的 IP 地址和端口号
      • Accept:告诉 Web 服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型
    • 常见的状态码
    • 请求方法
  • 相关阅读:
    Angular6在自定义指令中使用@HostBingDing() 和@HostListener()
    升级到Angular6后对老版本的RXJS代码做相应的调整
    关于Angular6版本升级和RXJS6新特性的讲解
    ANGULAR 使用 ng build --prod 编译报内存错误的解决办法
    在js内生成PDF文件并下载的功能实现(不调用后端),以及生成pdf时换行的格式不被渲染,word-break:break-all
    在js中获取页面元素的属性值时,弱类型导致的诡异事件踩坑记录,
    前端使用mobx时,变量已经修改了,为什么组件还是没变化,map类型变量,对象类型变量的值获取问题(主要矛盾发生在组件使用时)
    在Java中发送http的post请求,设置请求参数等等
    spring定时任务注解@Scheduled的记录
    js获取dom元素的子元素,父元素,兄弟元素小记
  • 原文地址:https://www.cnblogs.com/qiuxirufeng/p/10473018.html
Copyright © 2011-2022 走看看