• Web文件上传方法总结大全


      1. 表单上传

        这是传统的form表单上传,使用form表单的input[type=”file”]控件,可以打开系统的文件选择对话框,从而达到选择文件并上传的目的,它的好处是多浏览器兼容,它是web开发者最常用的一种文件上传方式。

        表单的代码如下:

        <form method="post" action="/upload" enctype="multipart/form-data">
            <input name="file" type="file3" accept="image/gif,image.jpg"/>
            <input name="token" type="hidden"/>
            <input type="submit" value="提交"/>
        </form>

        以下是表单上传几个关键点:

    • method=”post”: 采用post方式提交数据
    • enctype=”multipart/form- data”:采用multipart格式上传文件,此时request头会显示 Content-Type:multipart/form-data; boundary=—-WebKitFormBoundaryzr34cwJ67R95KQC9
    • action:标明上传的服务端处理地址
    • type=”file”:使用input的file控件上传
    • 如果是多文件批量上传,可以将input[type=”file”]的name属性设置为如:name=”file[]”
    • accept属性是HTML5的新属性,它规定了可通过文件上传提交的文件类型
    • 上传的触发事件可以是:input[type=”file”]的onChange触发,也可以由一个独立的按钮的onClick使整个表单提交,此时还可以用input[type=”hidden”]带一些其它的参数,比如Token来源验证等等。

      2.Ajax无刷新上传

        Ajax无刷新上传的方式,本质上与表单上传无异,只是把表单里的内容提出来采用ajax提交,并且由前端决定请求结果回传后的展示结果,不用像直接表单上传那样刷新和跳转页面。在这里,我们采用jQuery来作为操作DOM和创建ajax提交的js基础库。

        html代码片段如下:

        <form>
            <input id="file" name="file4" type="file"/>
            <input id="token" name="token" type="hidden"/>
        </form>

        javascript代码片段如下:

        $("#file").on("change", function(){
            var formData = new FormData();
            formData.append("file", $("#file")[0].files);
            formData.append("token", $("#token").val());
            $.ajax({
                url: basePath + "/upload",
                type: "POST",
                data: formData,
                processData: false,
                contentType: false,
                success: function(response){
                    // 根据返回结果指定界面操作
                }
            });
        });

        我们使用了file控件的change来触发上传事件,当然你也可以使用某个按钮来触发表单提交。提交数据时,我用到了FormData对象来发送二进制文件,FormData构造函数提供的append()方法,除了直接添加二进制文件还可以附带一些其它的参数, 作为XMLHttpRequest实例的参数提交给服务端。

        使用jQuery提供的ajax方法来发送二进制文件,还需要附加两个参数:

    • processData: false // 不要对data参数进行序列化处理,默认为true
    • contentType: false // 不要设置Content-Type请求头,因为文件数据是以 multipart/form-data 来编码

      3. Flash上传

        很 多时候上传的需求要求显示上传进度、中断上传过程、大文件分片上传等等,这时传统的表单上传很难实现这些功能,于是产生了使用Flash上传的方式,它采 用Flash作为一个中间代理层,代替客户端跟服务端通信,此外,它也对客户端的文件选择方面拥有更多的控制权,比input[type=”file”] 要大得多。

        在这里我使用了jQuery封装好的uploadify插件来进行演示,一般这类插件都自带了上传用的Flash文件,因为跟服务端回传的数据和展示跟客户端的交互,都是Flash文件的接口跟插件来对接的。

        <div id="file_upload"></div>

        html部分很简单,预留一个hook后,插件会在这个节点内部创建Flash的object,并且还附带创建了上传进度、取消控件和多文件队列展示等界面。

        $(function(){
            $("#file_upload").uploadify({
                auto: true,
                method: "Post",
                 120,
                height: 30,
                swf: './uploadify.swf',
                uploader: basePath + "/upload",
                formData: {
                    token: $("#token").val()
                },
                fileObjName: "file",
                onUploadSuccess: function(file, data, response){
                    // 根据返回结果指定界面操作
                }
            });
        });

        关于jQuery.uploadify可以访问了解:http://www.uploadify.com/documentation/。值得注意的是flash并不适合手机端应用,更好的解决方案是使用flash+html5来解决平台的兼容性问题。

      4. 截图粘贴上传

        截图粘贴上传的核心思想是,监听粘贴事件,然后获取剪切板中的数据,如果是一张图片,则触发上传事件。

        代码片段如下:

        $("textarea").on("paste", function(e){
            e.stopPropagation();
            var self = this;
            var clipboardData = e.originalEvent.clipboardData;
            if (clipboardData.items.length <= 0) {
                return;
            }
            var file = clipboardData.items[0].getAsFile();
            if (!file) {
                return;
            }
            var formData = new FormData();
            formData.append("file", file);
            formData.append("token", $("#token").val());
            $.ajax({
                url: basePath + "/upload",
                type: "POST",
                data: formData
            }).done(function(response) {
                // 根据返回结果指定界面操作
            });
            e.preventDefault();
        });

        从上面代码可以看出,上传的过程都是一样的,主要是获取文件的方式。 当进行粘贴(右键paste/ctrl+v)操作时,触发剪贴板事件’paste’,从系统剪切板获取内容,而系统剪切板的数据在不同浏览器保存在不同的位置:

    • IE内核:windows.clipboardData
    • 其它:e.originalEvent.clipboardData

      5. 拖拽上传

        拖拽上传的方式,支持的浏览器比较少,因为它用到了HTML5的两个新的属性(API)一个是Drag and Drop,一个是File API。

        上传域监听拖拽的三个事件:dragEnter、dragOver和drop,分别对应拖拽至、拖拽时和释放三个操作的处理机制,当然你也可以监听dragLeave事件。

        HTML5的File API提供了一个FileList的接口,它可以通过拖拽事件的e.dataTransfer.files来传递的文件信息,获取本地文件列表信息。

        File API在HTML5规范中只是草案,在 W3C 草案中,File 对象只包含文件名、文件类型和文件大小等只读属性。但部分浏览器在草案之外提供了一个名为 FileReader 的对象,用以读取文件内容,并且可以监控读取状态,它提供的方法有: “readAsBinaryString” ,”readAsDataURL” ,”readAsText” ,”abort” 等。

        代码片段如下:

        // dragenter
        $("#textarea").on("dragenter", function(e){
            e.preventDefault();
        });
        // dragover
        $("#textarea").on("dragover", function(e){
            e.preventDefault();
        });
        // drop
        $("#textarea").on("drop", function(e){
            e.stopPropagation();
            e.preventDefault();
            var files = e.originalEvent.dataTransfer.files;
            _.each(files, function(file) {
                if (!/^image*/.test(file.type)) {
                    return;
                }
                var fileReader = new FileReader();
                fileReader.onload = function() {
                    //uploadFile(file);
                };
                fileReader.readAsDataURL(file);
            });
        });

        拖拽上传过程中的几个关键点:

    • 在drop事件触发后通过e.dataTransfer.files获取拖拽文件列表,在jQuery中是e.originalEvent.dataTransfer.files
    • 拖拽上传仅支持图片,文件对象中file.type标识了文件类型。
    • 由于可能是多图拖拽,所以可以遍历图片上传,这里用了Underscore的each方法。
    • 这里用readAsDataURL读取文件内容为二进制文件,你还可以将其转换为Base64方式上传,只是http协议里面存在对非二进制数据的上传大小限制为2M。
    • 上传的过程跟前面的方式相同,即:创建FormData对象并发起Ajax请求。

      6. 拍照上传

        拍照上传可以是PC上的摄像头拍照上传也可以是手机等移动设备的拍照上传。手机上的拍照上传最常见就是我们使用微信发照片了。

        手机实现拍照上传的代码:

        <input type=file accept="image/*">
        <input type=file accept="video/*">

        ios 有拍照、录像、选取本地图片功能,部分android只有选取本地图片功能。

      7. 上传与安全

        上传文件时必须做好文件的安全性,除了前端必要的验证,如文件类型、后缀、大小等验证,重要的还是要在后台做安全策略。

        这里我列举几个注意点:

    • 后台需要进行文件类型、大小、来源等验证
    • 定义一个.htaccess文件,只允许访问指定扩展名的文件。
    • 将上传后的文件生成一个随机的文件名,并且加上此前生成的文件扩展名。
    • 设置上传目录执行权限,避免不怀好意的人绕过如图片扩展名进行恶意攻击,拒绝脚本执行的可能性。

    啦啦啦

    啦啦啦

      

    啦啦啦

  • 相关阅读:
    解决 Android SDK Manager不能下载旧版本的sdk的问题
    [置顶] 如何合并文件中的内容?
    JSTL解析——005——core标签库04
    C中的几组指针
    别动我的奶酪:CSV文件数据丢零现象及对策
    重载(overload),覆盖/重写(override),隐藏(hide)
    IOS 轻量级数据持久化 DataLite
    记录路径dp-4713-Permutation
    android 多媒体数据库详解
    Data Recovery Advisor(数据恢复顾问)
  • 原文地址:https://www.cnblogs.com/ClassNotFoundException/p/7538065.html
Copyright © 2020-2023  润新知