zoukankan      html  css  js  c++  java
  • Django补充

    CSRF_Token在页面中存放的几个位置

    1. 在form表单中

    <form action="" method="post">
        {% csrf_token %}
    {#    这样后端就会把csrf_token的值渲染到这,形成一个input的隐藏标签 #}
    {#    标签的name值为csrfmiddlewaretoken #}
    </form>

    形成的具体的隐藏标签如下

    2. 在ajax中

    如果是把csrf_token放在ajax中,有以下两个地方可以放入

    a. 在ajax属性的headers中

    $.ajax({
        url:"",  //不写代表向当前路径发送请求
        type:"post",
        headers:{"X-CSRFToken":"{{ csrf_token }}"},  //这里必须放在引号中,不然会被当成变量去找值
        data:{"name":"sss"},
        success:function (data) {
            
        }
    })

    b. 在ajax属性的data中

    $.ajax({
        url: "",
        type: "post",
        data: {"name":"sss", "csrfmiddlewaretoken": "{{ csrf_token }}"}
        success: function (data) {
            
        }
    })

    前后端传输数据的编码格式

    前后端传输数据的编码格式主要有三种

      1. urlencode编码,也是form表单和ajax默认的编码格式,用来传输一些字符信息

      2. formdata编码,主要是用来传输文件的编码格式

      3. application/json编码, 传送json格式的字符编码,ajax里才有

    下面分别通过form表单和ajax来讲解三个编码格式

    特别需要注意的是:request.POST只能解析urlencoded编码格式的数据(formdata如果

             发送字符串信息也会被放到POST中)

    form表单中

    前端代码,由于默认是urlencode编码格式,所以不写,那我们为什么知道默认是这个呢

    看一个测试,条件是不写编码格式发送post请求,查看网页中的编码格式

    我们可以看出,当我们不设置是,默认的content-type就是urlencoded

    <form action="/app02/test/" method="post">
        {% csrf_token %}
        <p>username:<input type="text" name="username"></p>
        <p>password:<input type="password" name="password"></p>
        <p><input type="file" name="myfile"></p>
        <p><input type="submit"></p>
    </form>
    前端代码

    后端代码

    # 后端接收数据代码
    def test(request):
        if request.method == "POST":
            # 当前端是urlencoded编码格式时
            print(request.POST)
            print(request.FILES)
            """
            <QueryDict: {'csrfmiddlewaretoken': ['tcg1gkqE6eRRfZ0qW74YhMmdqU86qtwqBo0iiudlf3LqVGBHcDP3Jo8hPIwxYU2q'], 
            'username': ['hsdn'],
             'password': ['sd'],
              'myfile': ['微信图片_20190714181534.jpg']}>
            <MultiValueDict: {}>
            """
            # 我们可以看出即使你传入了一个文件,也只会以字符串的形式把文件名传过来
    
            # 当前端是formdata编码格式时
            """
            <QueryDict: {'csrfmiddlewaretoken': ['p21tUBHwMs4TH0q7lQPYo6hDst6QxM6zxeLKWLudVhYsnH1oBmA3QI3HRhuh5dCz'], 
            'username': ['1123'], 'password': ['sd']}>
            <MultiValueDict: {'myfile': [<InMemoryUploadedFile: 微信图片_20190714181534.jpg (image/jpeg)>]}>
            """
            # 我们可以看到,文件不会被request.POST解析,而是被request.FILES解析
            # 我们可以把文件对象取出来然后操作
    
        return render(request, "blog-code.html")

    ajax中

    1. urlencoded编码格式

        $('#btn').click(function () {
            $.ajax({
                url:"",
                type:"post",
                headers:{"X-CSRFToken":"{{ csrf_token }}"},
                data:{
                    "username":$(".username").val(),
                    "password":$(".password").val(),
                    "myfile":$(".myfile").val()
                },
                success:function (data) {
                    alert(data)
    
                }
            });
        })
    前端代码
    后端代码
    if
    request.method == "POST": # 当前端是urlencoded编码格式时 print(request.POST) print(request.FILES) """ <QueryDict: {'username': ['asdsad'], 'password': ['sdsd'], 'myfile': ['C:\fakepath\微信图片_20190714181534.jpg']}> <MultiValueDict: {}> """ # 我们可以看到,文件的路径被以字符串的形式被传了过来

    2. formdata编码格式

    $('#btn').click(function () {
        //用ajax传文件需要使用内置对象FormData
        let formData = new FormData();  //生成一个内置对象
        //内置对象既可以放入普通的键值对,也可以放入文件
        formData.append("username",$(".username").val());
        formData.append("password",$(".password").val());
        //想要取出文件对象,我们需要先把jq对象转成js对象,再根据.files取出文件对象
        let fileObj = $('.myfile')[0].files[0];
        formData.append("myfile", fileObj);
        $.ajax({
            url:"",
            type:"post",
            //用ajax传文件需要加入以下两个参数
            contentType:false,
            processData:false,
            headers:{"X-CSRFToken":"{{ csrf_token }}"},
            data:formData,
            success:function (data) {
                alert(data)
    
            }
        });
    
    })
    前端代码
    后端代码
    def test(request):
        if request.method == "POST":
            # 当前端是formdata编码格式时
            print(request.POST)
            print(request.FILES)
            print(request.FILES.get("myfile").name)
        """
        <QueryDict: {'username': ['撒旦第'], 'password': ['sdsd']}>
        <MultiValueDict: {'myfile': [<InMemoryUploadedFile: 微信图片_20190714181534.jpg (image/jpeg)>]}>
        微信图片_20190714181534.jpg
        """
        # 后端代码我们可以看出来,字符串的数据被解析到POST中,文件数据被解析到FILES中
        # 并且我们可以通过文件对象.name 拿出文件名
        # 写到本地中
        with open(request.FILES.get("myfile").name, 'wb') as f:
            for line in request.FILES.get("myfile"):
                f.write(line)
        # 这个文件对象就相当于f对象,可以for  line  把每一行取出来

    3. application/json编码格式

    $('#btn').click(function () {
        //发送json格式的时候需要stringify以下
        $.ajax({
            url:"",
            type: "post",
            headers:{"X-CSRFToken":"{{ csrf_token }}"},
            contentType: "application/json"
            data: JSON.stringify({"username":$(".username").val()}),
            success: function (data) {
                alert(data)
            }
    
        })
    });
    前端代码
    后端代码
    if
    request.method == "POST": # 当前端是json编码格式时 print(request.POST) print(request.body) """ <QueryDict: {'{"username":"sd"}': ['']}> b'{"username":"sd"}' 我们可以看到,request.POST已经不是我们之间常见那种形式的对象, 他是把整个二进制字符串当成了一个key 而我们真正的json字符串则是被保存到了request.body中 实际上,当请求编码为json时,后端是不会对我们数据进行操作的 是整体放到body中,我们可以取出来反序列化 """
  • 相关阅读:
    理解MVC MVVM MVP设计模式
    跨域问题详解
    JWT认证
    Django缓存
    API文档自动生成
    DRF分页器
    DRF请求和响应,以及Response对象重新封装
    drf认证、权限、频率、过滤、排序、异常处理
    drf之视图组件以及自动化路由
    【python面向对象实战练习】植物大战僵尸
  • 原文地址:https://www.cnblogs.com/hesujian/p/11228314.html
Copyright © 2011-2022 走看看