Front-end file upload

Dian a front file uploads

The front page is generally used to implement file upload.
In an HTML document: <input type="file" />labels appear every time, a FileUpload object is created. The tag contains a text input field to enter a file name, there is a button used to open a file selection dialog to graphically select the file, value of the property tag to save the name of the file specified by the user.
Multiple choice: you can tag multiple choice by adding multiple property to support; if multiple files are selected, this value represents a file path is selected JavaScript can get to other file paths through the FileList property Input.
File information: It can be returned by input.files property - the return value is a FileList object that contains a list of many file file, name, type, size and other attributes list contains pictures.
Restricting file types: You can use the accept attribute of input, accept MIME type property accepts a comma-delimited string. Such as: accept = "image / png, image / jpeg" or accept = "png, .jpg, .jpeg." - PNG / JPEG
Select the file: onchange event will trigger input of;
Upload: Before uploading files using FileReader object to read specified file to the file, the file is converted to a binary string, and the object xhr, overrideMimeType attribute is set to text / plain; charset = x- user-defined-binary, binary finally received back before making a specific process.

The first: the classic form and upload input

The rear end of the form is provided aciton page, Required: enctype = "multipart / form-data", type = 'post'

<form action='uploadFile.php' enctype="multipart/form-data" type='post'>
  <input type='file'>
  <input type='hidden' name='userid'>  
  <input type='hidden' name='signature'>
  <button>提交</button>
</form>

使用input选择文件,设置好其他input的值,点击提交,将文件数据及签名等认证信息发送到form设置的action对应的页面,浏览器也会跳转到该页面。触发form表单提交数据的方式有2种,一种是在页面上点击button按钮或按钮触发,第二种是在js中执行form.submit()方法。
优点:使用简单方便,兼容性好,基本所有浏览器都支持。
缺点: 1. 提交数据后页面会跳转(下面会讲如何禁止页面跳转)。
2.因为是浏览器发起的请求,不是一个ajax,所以前端无法知道什么时候上传结束。
3. form表单里发送除文件外的数据,一般是新建一个type=hidden的input,value=‘需要传的数据’,每发送一个数据就需要一个input,一旦多了就会使得dom看起来比较冗余。
小技巧:
form表单提交数据后会自动跳转到action指定的页面,为了禁止页面跳转,可以在页面中新建一个空的ifame,比如name=‘upload’,然后设置form的target=“Uploader”,form有一个target的属性,规定在何处打开action,这样form提交数据后就会仍停留在当前页。代码如下:

<form action='uploadFile.url' enctype="multipart/form-data" type='post' target="uploaderPage">
	<input type='file'>
	<button>提交</button>
</form>
<ifrmae name='upload' id='uploaderPage'></iframe>

这样写的另一个好处是,可以知道什么时候上传完成并接收到后端的回调结果。比如上面这个例子,文件数据发送到了 ‘uploadFile.url’,假设该页面处理完数据后返回了一个地址,该地址会被写入到之前的iframe中。所以在ifame的onload函数触发时,也就是上传完成后,可以在iframe中读取到后端返回的数据。

var iframe = document.getElementById('uploadPage');
iframe.onload = function () {
	var doc = window.frames['uploaderPage'].document;
	var pre = doc.getElementsByTagName('pre');
	var obj = JSON.parse(pre[0].innerHTML);
}

Note that when using this method, there is a cross-domain iframe restrictions, created out of the iframe if the address of the current page addresses and different sources, will complain. In this case, it is recommended that everyone in the iframe onload function, again requesting a file interface to obtain an address to the back-end, rather than directly to the iframe read. Or return such data.

<script type="text/javascript">
	window.top.window.callback(data)
</script>

callback is a good agreement and the front end of the name, the function is triggered after the upload is complete and return to the back-end data.

The second: use formData upload. (Sub borrow form and do not borrow form)

With the ajax file upload form

<script src="jquery.min.js"></script>
<form id="uploadForm" enctype="multipart/form-data">
    <input type="file" name="file" id="file">
    <input type="button" value="Upload" id="upload" />
</form>
<script>
    $(function () {
        $('#upload').click(function () {
            $.ajax({
                url: "http://localhost:8080/img",
                type: "post",
                data: new FormData($('#uploadForm')[0]),
                cache: false,
                processData: false,
                contentType: false,
                success: function (res) {
                console.log(res)
                },
                error: function (err) {
                    console.log(err)
                }
            })
        })
    })
</script>

processData set to false. Because the data values are FormData objects, the data need not be processed.
<form>Tags Add enctype = "multipart / form-data " attribute.
cache set to false, you do not need to upload the file cache.
contentType set to false. Because it is a <form>form constructs FormData objects, and has been declared attribute enctype = "multipart / form-data ", it is here set to false.

Without the aid of ajax file upload form

<input type="file" name="file" id="file"><input type="button" value="Upload" id="upload" />
<script src="jquery.min.js"></script>
<script>
$(function () {
    $('#upload').click(function () {
        let file = $("#file")[0].files[0];
        //创建formdata对象
        let formData = new FormData();
        formData.append("file", file);
        $.ajax({
            url: "http://localhost:8081/images",
            type: "post",
            data: formData,
            cache: false,
            processData: false,
            contentType: false,
            // headers: { 'Content-Type': 'multipart/form-data' },
            success: function (res) {
                console.log(res)
            },
            error: function (err) {
                console.log(err)
            }
        })
   })
})
</script>

append () should be the second parameter file object, i.e. $('#file')[0].files[0].
contentType should be set to 'false'.
From the code $('#file')[0].files[0]can be seen in a <input type="file">label can upload multiple files, only you need to <input type="file">add multiple or multiple = "multiple" attribute in.
Js form data structure form, simple and efficient, but the minimum is only compatible with IE10, it needs to be compatible IE9 children's shoes to skip this method it.

  html:
    <input type='file'>
    js:
    var formData = new FormData();
    formData.append("userid", userid);
    formData.append("signature", signature);
    formData.append("file", file); //file是blob数据

//再用ajax发送formData到服务器即可,注意一定要是post方式上传

说明:第一种方法提到了创建多个type=‘hidden’的input来发送签名数据,这儿可以用formData.append方法来代替该操作,避免了dom中有多个input的情况出现。最后将file数据也append到formData发送到服务器即可完成上传。
优点:由于这种方式是ajax上传,可以准确知道什么时候上传完成,也可以方便地接收到回调数据。
缺点:兼容性差

第三种:使用fileReader读取文件数据进行上传。

HTML5的新api,兼容性也不是特别好,只兼容到了IE10。

var fr = new FileReader();
fr.readAsDataURL(file);
fr.onload = function (event) {
var data= event.target.result; //此处获得的data是base64格式的数据  
                    img.src = data;
ajax(url,{data} ,function(){})
}

上面获得的data可以用来实现图片上传前的本地预览,也可以用来发送base64数据给后端然后返回该数据块对应的地址。
优点: 同第二种
缺点:一次性发送大量的base64数据会导致浏览器卡顿,服务器端接收这样的数据可能也会出现问题

第四种:flash上传 参考jQuery封装好的uploadify插件

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

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

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

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

二丶图片上传和预览

方法一:使用js的FileReader对象

1、FileReader对象简介

1.检测浏览器对FileReader的支持

if(window.FileReader) {
	var fr = new FileReader();
	// add your code here
}else {
	alert("Not supported by your browser!");
}

调用FileReader对象的方法
FileReader 的实例拥有 4 个方法,其中 3 个用以读取文件,另一个用来中断读取。下面的表格列出了这些方法以及他们的参数和功能,
需要注意的是 ,无论读取成功或失败,方法并不会返回读取结果,这一结果存储在 result属性中。

方法名                  参数              		描述
abort                  none            			中断读取
readAsBinaryString	   file			  		将文件读取为二进制码
readAsDataURL		   file			  		将文件读取为 DataURL
readAsText			  file, [encoding]		将文件读取为文本

readAsText:该方法有两个参数,其中第二个参数是文本的编码方式,默认值为 UTF-8。这个方法非常容易
理解,将文件以文本方式读取,读取的结果即是这个文本文件中的内容。
readAsBinaryString:该方法将文件读取为二进制字符串,通常我们将它传送到后端,后端可以通过这段字符串存储文件。
readAsDataURL:这是例子程序中用到的方法,该方法将文件读取为一段以 data: 开头的字符串,这段字符 串的实质就是 Data URL,Data URL是一种将小文件直接嵌入文档的方案。这里的小文件通常是指图像与 html 等格式的文件。(其中base64的方式就是由此来获得的。。)

  1. FileReader handling events Introduction
    FileReader includes a complete event model for the state when capturing read the file, the following table summarizes these events.
    onabort trigger an interrupt
    is triggered when the onerror error
    onload file reads the trigger upon successful completion
    onloadend read the complete trigger, regardless of success or failure
    triggered when onloadstart read start
    onprogress reads
    the file once you start reading, result regardless of success or failure, the instance properties will be filled. If the read fails, the result is null, otherwise it is the result of the reading, the vast majority of the program will be successful in reading the file, grab this value.

     <p>
         <label>请选择一个文件:</label>
         <input type="file" id="file" />
         <input type="button" value="读取图像" onclick="readAsDataURL()" />
         <input type="button" value="读取二进制数据" onclick="readAsBinaryString()" />
         <input type="button" value="读取文本文件" onclick="readAsText()" />
     </p>
     <div id="result" name="result"></div>
    
    
     <script type="text/javascript">
         var result = document.getElementById("result");
         var file = document.getElementById("file");
         //判断浏览器是否支持FileReader接口
         if (typeof FileReader == 'undefined') {
             result.InnerHTML = "<p>你的浏览器不支持FileReader接口!</p>";
             //使选择控件不可操作
             file.setAttribute("disabled", "disabled");
         }
    
         function readAsDataURL() {
             //检验是否为图像文件
             var file = document.getElementById("file").files[0];
             if (!/image\/\w+/.test(file.type)) {
                 alert("看清楚,这个需要图片!");
                 return false;
             }
             var reader = new FileReader();
             //将文件以Data URL形式读入页面
             reader.readAsDataURL(file);
             reader.onload = function (e) {
                 var result = document.getElementById("result");
                 //显示文件
                 result.innerHTML = '<img src="' + this.result + '" alt="" />';
             }
         }
    
         function readAsBinaryString() {
             var file = document.getElementById("file").files[0];
             var reader = new FileReader();
             //将文件以二进制形式读入页面
             reader.readAsBinaryString(file);
             reader.onload = function (f) {
                 var result = document.getElementById("result");
                 //显示文件
                 result.innerHTML = this.result;
             }
         }
    
         function readAsText() {
             var file = document.getElementById("file").files[0];
             var reader = new FileReader();
             //将文件以文本形式读入页面
             reader.readAsText(file);
             reader.onload = function (f) {
                 var result = document.getElementById("result");
                 //显示文件
                 result.innerHTML = this.result;
             }
         }
    
     </script>
    

Image preview function 3, using the FileReader object implementation js upload pictures

<!DOCTYPE html>
<html>

<head>
    <meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="format-detection" content="telephone=no">
    <title>test</title>
    <script>
        //选择图片时预览功能
        function imageshow(source) {
            var file = source.files[0];
            var imageid = source.id;
            if (window.FileReader) {
                var fr = new FileReader();
                fr.onloadend = function (e) {
                    document.getElementById("portrait" + imageid).src = e.target.result;
                };
                fr.readAsDataURL(file);
            }
            document.getElementById("image" + imageid).style.display = "none";
            document.getElementById("show" + imageid).style.display = "block";
        }
    </script>
</head>

<body>
    <div>
        <div id="image1">
                  <p>上传截图</p>
            <input type="file" name="screenshot1" id="1" onchange="imageshow(this)" />
        </div>
            <div id="show1" style="display:none;">
                  <img src="" id="portrait1" width="100" height="70">
                </div>
            <div id="image2">
            <p>上传截图</p>
            <input type="file" name="screenshot2" id="2" onchange="imageshow(this)" />
        </div>
            <div id="show2" style="display:none;">
                  <img src="" id="portrait2" width="100" height="70">
               </div>
        <div id="image3">
            <p>上传截图</p>
            <input type="file" name="screenshot3" id="3" onchange="imageshow(this)" />
        </div>
          <div id="show3" style="display:none;">
                  <img src="" id="portrait3" width="100" height="70">
                </div>
    </div>
</body>

</html>

Option two: window.createObjectURL
directly on the code:

<!DOCTYPE html>
<html>

<head>
    <title>图片上传预览</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script src="http://www.codefans.net/ajaxjs/jquery-1.6.2.min.js"></script>
</head>

<body>
    <form name="form0" id="form0">
        <input type="file" name="file0" id="file0" multiple="multiple" />
        <br>
        <img src="" width="100" height="100" id="img0">
    </form>
    <script>
        $("#file0").change(function () {
            var objUrl = getObjectURL(this.files[0]);
            console.log("objUrl = " + objUrl);
            if (objUrl) {
                $("#img0").attr("src", objUrl);
            }
        });

        //取得该文件的url function getObjectURL(file) {
        var url = null;
        if (window.createObjectURL != undefined) {
            url = window.createObjectURL(file);
        } else if (window.URL != undefined) {
            url = window.URL.createObjectURL(file);
        } else if (window.webkitURL != undefined) {
            url = window.webkitURL.createObjectURL(file);
        }
        return url;
//}
    </script>
</body>

</html>

Guess you like

Origin blog.csdn.net/VIP__ID/article/details/93484347