form表单与ajax单个文件的上传

一、请求头之contentType

1、ContentType指的是请求体的编码类型,常见的类型共有3种:application/x-www-form-urlencoded、 multipart/form-data、application/json  

2、 application/x-www-form-urlencoded
这应该是最常见的 POST 提交数据的方式了。浏览器的原生表单,
如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。
    #可以用request.POST与request.GET获取到值

3、multipart/form-data
这又是一个常见的 POST 数据提交的方式。######我们使用表单上传文件时,必须让表单的 enctype 等于 multipart/form-data。######
    #可以用request.FILES获取到值

4、application/json
(1)application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。
由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。
(2)JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。
不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。
    #Django内置的没有json的解析器,需要我们在request.body中按照相应的规则去处理~

二、基于form表单的文件上传

1、路由

re_path('^put_file/$',views.put_file),

2、视图函数

def put_file(request):
    if request.method == 'GET':
        return render(request,'put_file.html')
    if request.method == 'POST':
        print(request.POST)  #<QueryDict: {'user': ['123']}>
        # 用request.FILES获取
        print(request.FILES)  # #<MultiValueDict: {'avatar': [<InMemoryUploadedFile: 1.jpg (image/jpeg)>]}>
        #上传文件——默认传到程序的根目录
        #获取文件对象
        #这个file_obj是一个文件句柄类型的数据
        file_obj = request.FILES.get('avatar')
        #注意这里:file_obj.name,以二进制方式写入
        #拼接路径 这里存放上传的文件的位置可以用绝对路径~这里我在静态文件夹中新建了一个upload文件夹存放上传的文件
        file_path = os.path.join(settings.BASE_DIR,'staticfiles','upload',file_obj.name)
        #按照绝对路径写入文件
        with open(file_path,'wb')as f:
            #django内置的方法chunks()方法
            #chunks()默认一次返回大小为经测试为65536B,也就是64KB,最大为2.5M,是一个生成器
            for chunk in file_obj.chunks():
                f.write(chunk)
        return HttpResponse('OK!')

3、模板文件——put_file.html

<form action='' method='post'  enctype="multipart/form-data">
    {% csrf_token %}
    用户名: <input type="text" name="user"> </br></br>
    文  件: <input type="file"  name="avatar"> </br></br>
    <input type="submit">
</form>

三、基于Ajax的文件上传

1、路由

re_path('index',views.ajax_upload,name='ajax_upload'),

2、视图函数

def ajax_upload(request):
    if request.method == 'POST':
        print(request.POST)

        print(request.FILES)
        # 注意 这里用的是formdata的键~
        print(request.FILES.get('file_obj'))

        # 这个file_obj是一个文件句柄类型的数据
        file_obj = request.FILES.get('file_obj')

        print(file_obj.name)  # default.jpg 本地文件的名称要跟他一致
        # 拼接路径
        file_path = os.path.join(settings.BASE_DIR, 'staticfiles', 'upload', file_obj.name)
        # 读文件
        with open(file_path, 'wb')as f:
            # django内置的方法chunks()方法  每次上传的都是一个固定大小的数据
            for chunk in file_obj.chunks():
                f.write(chunk)
        return HttpResponse('OK')
    else:
        return render(request,'ajax_upload.html')

3、模板文件——ajax_upload.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Ajax上传</title>
</head>
<body>
<div>
    {# csrf_token认证需要的标签 #}
    {% csrf_token %}
    用户名:<input id="user" type="text" name="username" placeholder="用户名">
    密码:<input id="pwd" type="password" name="password" placeholder="密码">
    头像:<input id="avatar" type="file" name="avatar">
    <input type="button" value="上传文件" id="btn">
</div>
</body>
<script src="{% static 'jquery-3.4.1.js' %}"></script>
{# 注意引入jquery.cookie.js 进行csrfmiddlewaretoken认证 #}
<script src="{% static 'jquery-cookie/jquery.cookie.js' %}"></script>
<script>
    $('#btn').click(function () {
        
        var username = $('#user').val();
        var password = $('#pwd').val();
        //取到的jquery对象转换成dom对象~然后调用dom对象的files方法获取所有的文件
        //这里是单个文件的上传~~取第一个就好了~~~
        var file_obj = $('#avatar')[0].files[0];

        {# 声明一个formdata对象 并将需要传递的数据append到里面去 #}
        {# 注意:是在ajax操作之前做的! #}
        var formdata = new FormData();
        formdata.append('uname',username);
        formdata.append('pwd',password);
        formdata.append('file_obj',file_obj);

        $.ajax({
            url:{% url 'ajax_upload'%},
            type:'post',
            data:formdata,
            // 从Cookie取csrftoken,并设置到请求头中,进行csrfmiddlewaretoken认证
            headers: {"X-CSRFToken": $.cookie('csrftoken')},  

            {# 用formdata进行ajax文件上传必须加这两个参数 #}
            processData: false ,    // 不处理数据
            contentType: false,    // 不设置内容类型

            success:function (data) {
                console.log(data);
            }
        })
    })
</script>
</html>
posted on 2019-05-19 11:44  江湖乄夜雨  阅读(522)  评论(0编辑  收藏  举报