Django中的文件上传+Ajax详细应用

【001】基于Ajax上传文件

原则:如果我们使用Ajax操作在涉及到文件上传时,那就要使用FormData

1.首先要明白:上传文件使用input输入框的类型是file:

2.后台我需要拿到前端传递过来的文件对象,注意文件对象并不在request.post里面,而是在request.files里面:

# 获取文件对象file_obj,如果想获取文件的名字,使用file_obj.name即可
file_obj = request.FILES.get("cFile")

3.contentType:笔者在上一节中说过即客户端告诉服务端决定以什么样的数据编码格式发送给服务端,在请求头中,如果没有特意指定该参数,那么默认就是以urlencoded的形式为我们组装数据。

注意contentType是前端页面在请求向服务端发送数据,具体以什么格式组装数据然后发送过去,就取决于contentType的类型,默认是如下的类型,就是以键值对键值对的形式组装发送过去:

4.根据上面所说,现在我要传输一个文件过去,因为键值对中涉及到一个文件,如果还是按照默认的编码方式发送过去,我们在服务端打印request.body,拿到的只能是一个文件名:

这显然不满足我们的要求,因为我们是需要文件对象的。所以不能采用默认的形式发送数据,因为涉及到二进制数据,怎么设置?昨天使用Ajax直接指定参数即可,现在我使用Form表单来传递包括二进制文件在内的数据,所以需要添加一个参数:enctype,这里我们选中multipart/form-data,如下:

我以后上传图片,音乐等二进制文件时,都可以结合form-data进行使用,当我们修改格式后,就可以看看请求头中的Content-Type:

然后再来看看服务端的打印结果:

request.FILES接收的是文件对象,InMemoryUploadFile是我们拿到的文件句柄,这样就上传头像了!

通过上面的例子可知,form-data既可以支持表单数据,例如我们打印request.POST打印出表单数据,又支持二进制数据,例如图片,音频等文件。但是urlencoded只支持表单数据。这是两者的根本区别,一定要区分开。

request.FILES是一个字典,现在我们得到一个文件对象:

通过文件句柄的name属性打印出图片的名字:

记住使用Ajax上传文件时候,input输入框的类型要修改为button,不要使用submit.

$(""button")表示选择 type="button" 的 <button> 元素和 <input> 元素。

通过Jquery获取二进制文件对象:

使用Ajax上传一个二进制文件时候,如何组装键值对的时候注意取出值:

1.首先通过Jquery拿到文件所属的input标签:

$("#cFile")

2.将Jquery对象转换为Dom对象:

$("#cFile")[0] 此时我们就拿到了dom对象

3.调用dom对象的files方法,拿到一个文件list:Filelist,接下来只需要获取

该文件列表的第一个元素即可:$("#cFile")[0].files[0]即可获取到文件对象

4.那我们能不能按照如下的方式写呢?

按照上述的方式这样写直接报错:

那是因为你传二进制数据,按照表单数据发送肯定是不行的;所以肯定不能按照上面的方式,那么Ajax利用的也是FormData,要想使用Ajax上传二进制文件就需要使用到FormData,我们也不需要什么form表单了,变为如下:

使用如下的形式发送数据:

直接将formData传递过去即可。点击发送依然有问题,那是因为Content-Type默认是urlencoded,现在我使用Ajax发送,那就要修改两个参数,都设置为False

前面我们说过,无论你的Data里面写什么数据,ajax发送的时候都会以contentType规定的格式对你的数据进行编码传送;你默认是urlencoded,那我就以
urlencoded的格式发送过去;如果你修改为Json,那我就以json的格式发送。

但是不是所有的情况都需要进行编码传送,例如我传递一个二进制文件,二进制没有必要进行编码,按照原来的文件格式发送即可。

Ajax发送数据的时候,首先会查看processData的值,如果为True,表明我需要对该数据进行处理后发送,至于做什么样的处理,就得问contentType了,contentType会告诉Ajax是把数据处理成urlencoded的形式,还是json字符串

也就是说两者配合工作,如果设置processData为False,表示我的数据是什么样子,你就将数据发送到服务器,让服务器自己接受。因此processData的值就只有两个,True:表示我对数据进行预处理,至于怎么处理,就是contentType要干的事,为False,那就告诉ajax不做处理,直接发送二进制数据即可。
因此processData设置为False,那么contentType也没用了,直接设置为False,将默认的urlencoded清空掉,如果你不设置,那么它默认又以urlencoded进行发送。

现在你不使用表单形式(urlencoded)的形式进行发送了,那么我传送csrf_token的时候也是二进制,那肯定也过不了,所以我们得在请求头重添加一个X-CSRFToken:

这里是在网页中的input输入框中取值,所以使用csrfmiddlewaretoken,如果从cookie中取值,那就得使用csrftoken,这里要注意区分。

综上所述,上传文件有两种形式:

总结:上传文件有两种方式:

【01】.form表单数据进行提交:

两处修改:1.在form标签后面增加一个属性enctype="multipart/form-data"

2.由于上传的文件是二进制数据,所以还需要修改contentType,让它变为formdata:

【02】使用Ajax提交:

1.实例化表单数据对象:

这里面的数据是表单数据还是非表单数据都可以

2.然后按照FormData实例化的结果发送过去即可:

最后分享一个实际的例子供各位参考:

$(document).ready(function () {
    // 为每个input输入框绑定的blur事件,并将值通过Ajax发送给后台进行校验
    $("#id_username").blur(function () {
        $.ajax({
            url:"/validate_username/",
            type:"get",
            data:{"username": $("#id_username").val()},
            success:function (data) {
                if(data.flag){
                    alert("This username has benn registered");
                    // $("#error").html("用户名已被注册");
                }else{
                    console.log(data.flag);
                }
            }
        });
        $("#register_btn").submit();
    });

      var handlerPopup = function (captchaObj) {

        // 成功的回调
        captchaObj.onSuccess(function () {
            function foo() {
            $(".error").html("");
        }
            var validate = captchaObj.getValidate();
            var $formData = new FormData();
            $formData.append("username",$(‘#id_username‘).val());
            $formData.append("password", $("#id_password").val());
            $formData.append("password_again", $("#id_password_again").val());
            $formData.append("email", $("#id_email").val());
            $formData.append("mobile", $("#id_mobile").val());
            $formData.append("avatar_image", $("#avatar_file")[0].files[0]);
            $formData.append("csrfmiddlewaretoken", $("input[name=‘csrfmiddlewaretoken‘]").val());
            $formData.append("geetest_challenge", validate.geetest_challenge);
            $formData.append("geetest_validate", validate.geetest_validate);
            $formData.append("geetest_seccode", validate.geetest_seccode);

            $.ajax({
                url: "/pc-geetest/ajax_register_validate", // 进行二次验证
                type: "post",
                dataType: "json",
                data: $formData,
                processData: false,
                contentType:false,
                success: function (data) {
                    if (data && (data.status === "success")) {
                        // 注册数据满足规则,提示注册成功的信息,3秒后跳转到登入界面
                        $("#register_success").html("Congratulations For Register");
                        setTimeout(foo, 3000);
                    } else {
                        //注册数据不满足规则,那就提示错误信息, error_msg是一个字典
                         // 当第一次提示有3个字段错误的时候,我修改一个错误后,那么还剩下2个,刚才剩下的那个
                        //错误应该消失,因为这又是一个ajax请求。
                        $("span").html("");
                        $(".form-group div").each(function () {
                        //其次应该将input输入框的错误红色提示消掉,根据后面的可知,我们应该将input输入框的父级标签div
                            $(this).removeClass("has-error");
                        });

                        $.each(data.error_msg, function (key, value) {
                            console.log(data.error_msg);
                            //1.新建span标签,并增加相应的样式
                            $span = $("<span>");
                            $span.addClass("pull-right").css("color", "red").html(value[0]);
                            //2.将span标签放在对应input输入框下面,通过$("#id_"+key)实现
                            // .parent()是获取input标签的父级标签,要想让整个input输入框变红,必须为div
                            $("#id_"+key).after($span).parent().addClass("has-error");
                            // 3.判断全局钩子函数中定义的密码是否错误
                            if(key === "__all__"){
                                $("#id_password_again").after($span).parent().addClass("has-error");
                            }
                        })
                    }
                }
            });
        });
        $("#popup-submit").click(function () {
            captchaObj.show();
        });
        // 将验证码加到id为captcha的元素里
        captchaObj.appendTo("#popup-captcha");
    };

     // 验证开始需要向网站主后台获取id,challenge,success(是否启用failback)
    $.ajax({
        url: "/pc-geetest/register?t=" + (new Date()).getTime(), // 加随机数防止缓存
        type: "get",
        dataType: "json",
        success: function (data) {
            initGeetest({
                gt: data.gt,
                challenge: data.challenge,
                product: "popup",
                offline: !data.success
            }, handlerPopup);
        }
    });
});

Django文件上传:https://www.cnblogs.com/linjiqin/p/3731751.html

https://www.cnblogs.com/zhaopengcheng/p/5633154.html

http://blog.csdn.net/a18852867035/article/details/66976028

https://www.cnblogs.com/nulige/p/6582355.html

原文地址:https://www.cnblogs.com/pyspark/p/8167851.html

时间: 2024-10-21 06:03:02

Django中的文件上传+Ajax详细应用的相关文章

django中处理文件上传文件

1 template模版文件uploadfile.html 特别注意的是,只有当request方法是POST,且发送request的<form>有属性enctype="multipart/form-data"时,request.FILES中包含文件数据,否则request.FILES为空. <form method="post" action="" enctype="multipart/form-data"

django 快速实现文件上传

前言 对于web开来说,用户登陆.注册.文件上传等是最基础的功能,针对不同的web框架,相关的文章非常多,但搜索之后发现大多都不具有完整性,对于想学习web开发的新手来说就没办法一步一步的操作练习:对于web应用来说,包括数据库的创建,前端页面的开发,以及中间逻辑层的处理三部分. 本系列以可操作性为主,介绍如何通过django web框架来实现一些简单的功能.每一章都具有完整性和独立性.使用新手在动手做的过程中体会web开发的过程,过程中细节请参考相关文档. 本操作的环境: ==========

Django学习之文件上传

Django学习之文件上传 就这么六步! 一.settings配置文件中配置 MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'medias').replace('\\', '/')#media即为图片上传的根路径 二.url路由中配置 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index,name='index'), ] +

SF:salesforce中,文件上传的接收对象

使用Attachment,做文件的上传: 上传的内容,最终会存放到sf的Attachment对象里. 使用<apex:inputFile>组件上传文件: 上传的内容,会存放到sf的Document对象里. 使用sf中的,Content App中的Library来存放Content文件: 上传的文件,会在ContentWorkspace对象(Library),ContentVersion对象(Content)来存放具体的文件的内容(包括,二进制的文件等等,但是,它需要一个ContentDocum

struts2中实现文件上传功能

在web项目中,文件上传.头像上传这样的功能经常是要用到的,下面就以在struts2中实现文件上传功能为例子,简单地理一下文件上传功能的编码思路. 项目目录结构 项目源代码 web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:x

struts2中的文件上传和下载

天下大事,必做于细.天下难事,必作于易. 曾经见过某些人,基础的知识还不扎实就去学习更难的事,这样必然在学习新的知识会很迷惑结果 再回来重新学习一下没有搞懂的知识,这必然会导致学习效率的下降!我写的这篇上传和下载都很基础. 十分适合初学者! jsp:页面 <!--在进行文件上传时,表单提交方式一定要是post的方式,因为文件上传时二进制文件可能会很大,还有就是enctype属性,这个属性一定要写成multipart/form-data, 不然就会以二进制文本上传到服务器端--> <for

在WebBrowser中通过模拟键盘鼠标操控网页中的文件上传控件

在WebBrowser中通过模拟键盘鼠标操控网页中的文件上传控件 引言 这两天沉迷了Google SketchUp,刚刚玩够,一时兴起,研究了一下WebBrowser. 我在<WebBrowser控件使用技巧分享>一文中曾谈到过"我现在可以通过WebBrowser实现对各种Html元素的操控,唯独无法控制Html的上传控件",出于安全原因,IE没有对上传控件提供操控支持,这使得我们没法像控制其他控件一样用简单的代码进行赋值. 比较实际的解决方案就是模拟操作了,下面我就将演示

如何在Web页面中集成文件上传功能

当前,个人主页制作非常流行.当用户开发好自己的页面时,需要将文件传输到服务器上,解决这个问题的方法之一 是运行FTP服务器并将每个用户的FTP默认目录设为用户的Web主目录,这样用户就能运行FTP客户程序并上传文件到指定的 Web目录.由于Windows NT 和 Windows98均不提供直接的基于窗口形式的FTP客户程序,用户必须懂得如何使用基于命令行 的FTP客户,或掌握一种新的基于窗口形式的FTP客户程序.因此,这种解决方案仅对熟悉FTP且富有经验的用户来说是可行 的. 如果我们能把文件

Java中的文件上传和下载

文件上传原理: 早期的文件上传机制: 在TCP/IP中.最早出现的文件上传机制是FTP.他是将文件由客户端发送到服务器的标准机制. jsp中的文件上传机制: 在jsp编程中不能使用FTP的方法来上传文件,这是由jsp运行机制所决定的.jsp中通过将表单元素设置Method="post" enctype="multipart/form-data" 属性,让表单以二进制编码的方式提交,在接收次请求的Servelet中用二进制流来获取内容,从而实现文件的上传. 表单的en