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中,我们可以取出来反序列化 """
原文地址:https://www.cnblogs.com/hesujian/p/11228314.html