前端之web上传文件的方式

前端之web上传文件的方式

本节内容

  1. web上传文件方式介绍
  2. form上传文件
  3. 原生js实现ajax上传文件
  4. jquery实现ajax上传文件
  5. form+iframe构造请求上传文件

1. web上传文件方式介绍

在web浏览器上传文件一般有以下几种方式:

  • form表单上传文件
  • 原生js实现ajax上传文件
  • jquery实现ajax上传文件
  • form+iframe上传文件

其中form提交数据之后会整个刷新页面;
js通过ajax上传文件虽然不会刷新整个页面,但是他们都是通过使用formdata对象实现的,formdata对象在老版本的浏览器中并不支持;
为了兼容老版本浏览器,使用iframe方式提交;

下面几节就分别就这几种方式实现上传文件来举例说明。

2. form上传文件

这是最原始的一种方式,最开始学习web的时候就是使用这种方式提交。
注意:在form表单中如果要上传文件,一定要设置这个参数: enctype=”multipart/form-data”表示封装数据类型,把数据分成一个一个小段传输。

html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .show-img{
            display: inline-block;
            width: 200px;
            height:200px;
        }
    </style>
</head>
<body>
    <h1>form表单上传文件</h1><hr>
    <form action="/test/" method="POST" enctype="multipart/form-data">
        <p>名称:<input type="text" name="user"></p>
        <p>文件:<input type="file" name="testfile"></p>
        <p><input type="submit" value="提交"></p>
    </form>
    {% for i in imglist %}
        <img class="show-img" src="/{{ i.0 }}">
    {% endfor %}
</body>
</html>

在后端要注意上传过来的文件是通过req.FILES.get() 方法接收的。
后端代码:

def test(req):
    if req.method=="GET":
        imglist=models.Img.objects.all().values_list("img_path")
        return render(req,"test.html",{"imglist":imglist})
    elif req.method=="POST":
        user=req.POST.get("user")
        file=req.FILES.get("testfile")
        path=os.path.join("static","imgs",file.name)
        with open(path,"wb") as f:
            for chunk in file.chunks():
                f.write(chunk)
        print(user,file.name,file.size)
        models.Img.objects.create(img_path=path)
        return redirect("/test/")

3. 原生js实现ajax上传文件

js源码:

document.getElementById("js_post").onclick=function(){
    var xml=new XMLHttpRequest();
    var data=new FormData; //创建formdata对象
    data.append("testfile",document.getElementById("file_upload").files[0]);//找到对象之后的file[0]对应的就是文件对象
    xml.open("POST","/test/",true);
    xml.onreadystatechange=function(){
        if(xml.readyState==4 && xml.status==200){  //判断状态到4了并且返回状态码是200时才做操作
            var rsp_data=JSON.parse(xml.responseText);  //反序列化
            if (rsp_data.state){
                var url="/"+rsp_data.data;  //拼接路径
                var obj=document.createElement("img");  //创建标签
                obj.className="show-img";  //给标签加样式
                obj.src=url;  //给标签加url
                document.getElementById("imgs").appendChild(obj);
            }
        }
    };
    xml.send(data)
}
`

html源码:

<hr><h1>ajax上传文件</h1><hr>
<p>文件:<input id="file_upload" type="file" name="testfile"></p>
<p><button id="js_post">原生js提交</button>  <button id="jquery_post">jquery提交</button></p>
<div id="imgs">
    {% for i in imglist %}
        <img class="show-img" src="/{{ i.0 }}">
    {% endfor %}
</div>

后端源码:

def test(req):
    if req.method=="GET":
        imglist=models.Img.objects.all().values_list("img_path")
        return render(req,"test.html",{"imglist":imglist})
    elif req.method=="POST":
        user=req.POST.get("user",None)
        file=req.FILES.get("testfile")
        path=os.path.join("static","imgs",file.name)
        with open(path,"wb") as f:
            for chunk in file.chunks():
                f.write(chunk)
        print(user,file.name,file.size)
        models.Img.objects.create(img_path=path)
        # return redirect("/test/")
        msg={"code":200,"state":True,"data":path}
        return HttpResponse(json.dumps(msg))

注意:FormData对象在添加文件对象的时候并不是把标签直接给append进去,而是找到标签之后.file(0)才是文件对象

4. jquery实现ajax上传文件

这里的html代码和后端代码相对上面没有改变,这里就不列出来了。
jquery代码:

$("#jquery_post").on("click",function(){
            var data=new FormData;
            data.append("testfile",document.getElementById("file_upload").files[0]);
            $.ajax({
                url:"/test/",
                type:"POST",
                dataType:"JSON",
                data:data,
                contentType: false,
                processData: false,
                success:function(rst){
                    if(rst.state){
                        var url="/"+rst.data;
                        $(‘<img class="show-img" src="‘+url+‘">‘).appendTo("#imgs")
                    }
                }
            })
        })

注意:jquery的ajax会自动把我们的数据转换成字符串,不想转换时需要在ajax里面写入:contentType: false,processData: false,

5. form+iframe构造请求上传文件

html代码:

<hr><h1>form+iframe上传文件</h1><hr>
    <p><iframe id="uploadfile" name="uploadfile" style="display: none"></iframe></p>  <!--注意这里的name要和form中的target一致-->
    <form target="uploadfile" action="/test/" method="POST" enctype="multipart/form-data">
        <p>名称:<input type="text" name="user"></p>
        <p>文件:<input type="file" name="testfile"></p>
        <p><input type="submit" value="提交"></p>
    </form>
    <div id="imgs">
        {% for i in imglist %}
            <img class="show-img" src="/{{ i.0 }}">
        {% endfor %}
    </div>

注意:这里的iframe的name的值一定要和form的target的值一样,这样才能实现绑定

js代码:

$("#uploadfile").on("load",function(){  //iframe里面有个方法是onload,当上传数据成功之后服务器返回数据时才会触发该事件
            var rst=JSON.parse(this.contentDocument.body.textContent);//拿到iframe里面的内容需要通过contentDocument才能拿到里面的dom对象
            if (rst.state){
                var url="/"+rst.data;
                        $(‘<img class="show-img" src="‘+url+‘">‘).appendTo("#imgs")
            }
        })

注意:拿到iframe里面的内容需要通过contentDocument才能拿到里面的dom对象
经过实际检测,当鼠标点击提交速度比较快时,js通过ajax提交数据没有问题,但是iframe就无法提交所有数据。。。
原因是ajax是异步加载的,而iframe更像是通过浏览器打开了一个新标签,等待服务端传输回来的数据。所以,当提交速度过快时无法达到相应的效果。
使用iframe的唯一一个好处目前来看也就是兼容老版本的浏览器罢了。。。
随着时间的流逝,这种方式终将被淘汰。

时间: 2024-10-29 19:08:24

前端之web上传文件的方式的相关文章

异步上传文件多种方式归纳

最近在做异步上传文件的工作,用到了一些库,这里归纳下,暂且不考虑异常处理,仅作为demo. 1.不用任何插件,利用iframe,将form的taget设为iframe的name,注意设为iframe的id是没用的,跟网上很多说的不太一致 iframe_upload.htm <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtm

Jquery_异步上传文件多种方式归纳

1.不用任何插件,利用iframe,将form的taget设为iframe的name,注意设为iframe的id是没用的,跟网上很多说的不太一致 iframe_upload.htm <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns=&

Web上传文件的原理及实现

现在有很多Web程序都有上传功能,实现上传功能的组件或框架也很多,如基于java的Commons FileUpload.还有Struts1.x和Struts2中带的上传文件功能(实际上,Struts2在底层也使用了Commons FileUpload). 虽然现在有很多上传组件可以利用,但是了解Web上传文件的原理,对于处理突然出现的问题会有很大的帮助,下面就来讲一下通过浏览器上传文件的基本原理.在了解了原理之后,就可以非常容易地自制满足自身需要的上传组件了. 众所周知,在客户端代码中需要使用<

[转]文件上传原理:Web上传文件的原理及实现

现在有很多Web程序都有上传功能,实现上传功能的组件或框架也很多,如基于java的CommonsFileUpload.还有Struts1.x和Struts2中带的上传文件功能(实际上,Struts2在底层也使用了CommonsFileUpload).在asp.net中也有相应的上传文件的控件. 虽然现在有很多上传组件可以利用,但是了解Web上传文件的原理,对于处理突然出现的问题会有很大的帮助,下面就来讲一下通过浏览器上传文件的基本原理.在了解了原理之后,就可以非常容易地自制满足自身需要的上传组件

Asp.Net Mvc异步上传文件的方式

今天试了下mvc自带的ajax,发现上传文件时后端action接收不到文件, Request.Files和HttpPostedFileBase都接收不到.....后来搜索了下才知道mvc自带的Ajax不支持文件上传,无奈之下只能用其他的方式 第一种方式:通过 jquery的ajaxSubmit --->(先引入jQuery脚本)需要引入jquery.form.min.js(可以通过NuGet下载) 直接上代码 @{ Layout = null; } <!DOCTYPE html> <

web上传文件——python

上传文件 a. Form表单上传,页面刷新(基本不用这种方式) b. Ajax方式: $(function () { $('#btn1').click(function () { var fm = new FormData(); fm.append('fffff', document.getElementById('ggggg').files[0]); fm.append('usernmae','root'); $.ajax({ url: "/ajax-upload/", type:

Servlet上传文件直接处理方式

在开发的过程当中,经常遇到用文件上传的方式批量处理数据的方式,以前碰到的情况是先将文件保存到本地的临时文件,然后用poi的方式来进行处理,但是实际上,操作过程只是简单的读取操作,所以就不用那么复杂,下面记录了用servlet的javax.servlet.http.Part包的方式来处理这个功能.代码如下: Part part=request.getPart("标签name"); String filename=getFileName(part.getHeader("conte

.NET Core 2.1 Web 上传文件 关于System.IO.DirectoryNotFoundException

在ASP.NET Web开发练习中,想要完成上传文件的功能: 代码为: View: 1<form method="post" asp-controller="Register" asp-action="SetIcon" enctype="multipart/form-data"> 2 <input name="file" type="file" accept="

本地向服务器上传文件的方式-本地资源映射到服务器

本地向服务器传文件一定使不少刚接触服务器端工作的人疑惑,笔者研究生期间参与维护学校科技部的ASP.NET的IIS服务器,服务器上没有安装FTP工具,为了安全考虑网络也没有打开,windows自带的FTP服务也没有打开的情况下,远程连接时使用本地磁盘映射方法很方便实现本地与服务器的交互. 下面介绍两种方式交互(本地主机win10,远程win2003): 本地磁盘映射到服务器方式的步骤: 1 win + R 输入mstsc指令,打开远程桌面,输入ip 2点击显示选项 点击本地资源>详细信息 选择磁盘