[Transfer] Detailed explanation of file attribute

    The inability to directly access files on the user's computer has always been a major hurdle in Web application development. Before 2000, the only way to deal with files was to include an <input type="file"> field in a form, and that was it. The purpose of FileAPI (File API) is to provide web developers with a secure way to access files in a user's computer on the client side and better perform operations on those files. This article will introduce the File API in detail

  [Note] IE9 - browser does not support

File

  The File API adds some interfaces to directly access file information based on the file input fields in the form. HTML5 adds a files collection to the DOM for the file input element. When one or more files are selected through the file input field, the files collection will contain a set of File objects, one for each File object. Each File object has the following read-only properties

  name: the file name in the local file system

  size: the size of the file in bytes

  type: string, MIME type of the file

  lastModifiedDate: string, the time the file was last modified

  By listening to the change event and reading the files collection, you can know the information of each selected file

copy code
<input type="file" id="file1">
<div id="result"></div>
<script>
file1.onchange = function(){
    var data = file1.files [0];
    result.innerHTML = 'type:' + data.type + '<br>size:' + data.size + '(bytes)<br>name:' + data.name + '<br>modification time:' + data.lastModifiedDate;
}
</script>
copy code

 

[Hidden file input]

  Modern browsers support hiding the default file input box <input> element and use a custom interface to act as a button that opens a file selection dialog. It is very simple to implement, just use the style display:none to hide the original file input box, and then call its click() method when needed.

  [Note] IE9 - browser does not support

copy code
<input type="file" id="file1" style="display:none">
<button id="btn">按钮</button>
<div id="result"></div>
<script>
btn.onclick = function(){
    file1.click();
}
file1.onchange = function(){
    result.innerHTML = file1.files[0].name;
}
</script>
copy code

 

FileReader

  The function of the File API does not stop there, and even the data in the file can be read through the FileReader type it provides

【Constructor】

  Use the FileReader() constructor to create a FileReader object

var reader = new FileReader();

【Attributes】

  error: Indicates an error occurred while reading the file (read-only)

  readyState: Indicates the current state of the FileReader object, the value is one of the state constants (read-only)

  The state constants have the following three

Constant name value description
EMPTY 0 has not loaded any data yet
LOADING 1 data is being loaded
DONE 2 has completed all read requests

  result: Indicates the content of the read file. This attribute is only valid after the read operation is completed, and the format of the data depends on which method the read operation is initiated by (read-only)

【method】

  The FileReader type implements an asynchronous file reading mechanism. Think of FileReader as XMLHttpRequest, except that it reads the file system, not the remote server. In order to read the data in the file, FileReader provides the following methods

  abort() : abort the read operation

  readAsText (file or Blob, encoding): Read the content of the File or Blob object in plain text, and save the read text in the result property. The second parameter (optional) is used to specify the encoding type, the default is UTF-8

  readAsDataURL(file or Blob) : Read the content of the File or Blob object and save the file as a data URI (Base64 encoded) in the result attribute

  readAsBinaryString(file or Blob) : Read the contents of the File or Blob object and save a string in the result property, each character in the string represents a byte

  readAsArrayBuffer(file or Blob) : Reads the contents of a File or Blob object and saves an ArrayBuffer containing the contents of the file in the result property

  [Note] IE browser does not support readAsBinaryString() method

  These methods of reading files provide great convenience for flexible processing of file data. For example, an image file can be read and saved as a data URI so that it can be displayed to the user, or the file can be read as text for parsing convenience

【event】

  Since the reading process is asynchronous, FileReader also provides several events

  onabort : called when a read operation is aborted

  onerror : called when an error occurs in the read operation

  onload : called when a read operation completes successfully

  onloadend:当读取操作完成时调用,不管是成功还是失败。该处理程序在onload或者onerror之后调用

  onloadstart:当读取操作将要开始之前调用

  onprogress:在读取数据过程中周期性调用

  在正常情况下,读取文件时,首先触发loadstart事件,此时的readyState为1,result为空

  接着,每过50ms左右,就会触发一次progress事件,通过事件对象可以获得与XHR的progress事件相同的信息(属性):lengthComputable、loaded和total。另外,尽管可能没有包含全部数据,但每次progress事件中都可以通过FileReader的result属性读取到文件内容,readyState仍然是1

  当文件读取完成时,触发load事件,此时的readyState为2,result为文件内容;如果发生了error事件,就不会发生load事件

copy code
<input type="file" id="file1">
<div id="result"></div>
<script>
/*
[loadstart]readyState:1;result:
[progress]readyState:1;result:h3{color: #F44336;}
[load]readyState:2;result:h3{color: #F44336;}
[loadend]readyState:2;result:h3{color: #F44336;}
*/
file1.onchange = function(){
    var reader = new FileReader();
    reader.readAsText(file1.files[0]);
    reader.onloadstart = function(e){
        console.log('[loadstart]readyState:' + reader.readyState + ';result:' + reader.result);
    }
    reader.onload = function(e){
        console.log('[load]readyState:' + reader.readyState + ';result:' + reader.result);
    }
    reader.onloadend = function(e){
        console.log('[loadend]readyState:' + reader.readyState + ';result:' + reader.result);
    }
    reader.onprogress = function(e){
        console.log('[progress]readyState:' + reader.readyState + ';result:' + reader.result);
    }
}
</script>
copy code

  由于种种原因无法读取文件,就会触发error事件。触发error事件时,相关的信息将保存到FileReader的error属性中。这个属性中将保存一个对象,该对象只有一个属性code,即错误码。这个错误码是1表示未找到文件,是2表示安全性错误,是3表示读取中断,是4表示文件不可读,是5表示编码错误

reader.onerror = function(){
    output.innerHTML = "Could not read file, error code is " + reader.error.code;
}; 

  如果想中断读取过程,可以调用abort()方法,这样就会触发abort事件

  在触发load、error或abort事件后,会触发另一个事件loadend。loadend事件发生就意味着已经读取完整个文件,或者读取时发生了错误,或者读取过程被中断

 

重要的缩略图

  使用FileReader对象的 readAsDataURL() 方法完成对文件的读取,再通过 File对象的 type属性 筛选出图片

copy code
<img id="uploadPreview" style="width: 100px; height: 100px;" src="data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Csvg%20width%3D%22153%22%20height%3D%22153%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%3Cg%3E%0A%20%20%3Ctitle%3ENo%20image%3C/title%3E%0A%20%20%3Crect%20id%3D%22externRect%22%20height%3D%22150%22%20width%3D%22150%22%20y%3D%221.5%22%20x%3D%221.500024%22%20stroke-width%3D%223%22%20stroke%3D%22%23666666%22%20fill%3D%22%23e1e1e1%22/%3E%0A%20%20%3Ctext%20transform%3D%22matrix%286.66667%2C%200%2C%200%2C%206.66667%2C%20-960.5%2C%20-1099.33%29%22%20xml%3Aspace%3D%22preserve%22%20text-anchor%3D%22middle%22%20font-family%3D%22Fantasy%22%20font-size%3D%2214%22%20id%3D%22questionMark%22%20y%3D%22181.249569%22%20x%3D%22155.549819%22%20stroke-width%3D%220%22%20stroke%3D%22%23666666%22%20fill%3D%22%23000000%22%3E%3F%3C/text%3E%0A%20%3C/g%3E%0A%3C/svg%3E" alt="Image preview" />
<input type="file" id="file1" style="display:none">
<button id="btn">选择图片</button>
<span id="msgName"></span>
<script>
btn.onclick = function(){
    file1.click();
}
file1.onchange = function(){
    var file = file1.files[0];
    //如果一个文件被选中
    if(file){
        //一张图片被选中
        if (/image/.test(file.type)){
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = function(){
                uploadPreview.src = reader.result;
                msgName.innerHTML = file.name;
            }
        //其他格式文件被选中
        } else {
            alert("You must select a valid image file!");
        }                
    }    
}
</script>
copy code

 

Blob URL

  使用Blob URL,也可以用来显示缩略图

copy code
<input id="file1" type="file" accept="image/gif,image/jpeg,image/jpg,image/png,image/x-icon"  style="display:none">
<button id="btn">选择图片</button>
<div id="fileList"></div>
<script>
btn.onclick = function(){file1.click();}
//保存图片的名称
var dataArr = [];
file1.onchange = function(){
    var file = file1.files[0];
    //如果一个文件被选中
    if(file){
        var name = file.name;
        var id = name.split('.').join('_');
        //检测图片是否已经被存储过
        if(dataArr.indexOf(id) > -1){
            //将保存过的图片转移到最下方
            fileList.appendChild(document.getElementById(id));
        }else{
            if(/image/.test(file.type)){
                dataArr.push(id);
                var img = document.createElement('img');
                img.onload = function(){
                    URL.revokeObjectURL(img.src);
                }
                img.src= URL.createObjectURL(file);
                img.height = 60;
                var oDiv = document.createElement('div');
                oDiv.id = id;
                var oSpan = document.createElement('span');
                oSpan.innerHTML = name + ":" + file.size + " bytes";
                oDiv.appendChild(img);
                oDiv.appendChild(oSpan);
                fileList.appendChild(oDiv);                
            }
        }
    }    
}
</script>
copy code

 

文件内容

  readAsText() 可以以字符串形式读取并显示文件内容

copy code
<input id="file1" type="file"  style="display:none">
<button id="btn">选择文件</button>
<div id="fileData" style="border:1px solid black;width:300px;overflow:auto"></div>
<script>
btn.onclick = function(){file1.click();}
file1.onchange = function(){
    var file = file1.files[0];
    //如果一个文件被选中
    if(file){
        var reader = new FileReader();
        reader.readAsText(file);
        reader.onload = function(){
            fileData.innerHTML = reader.result;
        }
    }         
}
</script>
copy code

 

拖放选择

  围绕读取文件信息,结合使用HTML5拖放API和文件API,能够创造出令人瞩目的用户界面:在页面上创建了自定义的放置目标之后,你可以从桌面上把文件拖放到该目标。与拖放一张图片或者一个链接类似,从桌面上把文件拖放到浏览器中也会触发drop事件。而且可以在event.dataTransfer.files中读取到被放置的文件,当然此时它是一个File对象,与通过文件输入字段取得的File对象一样

  [注意]IE9-浏览器不支持event.dataTransfer

  从电脑上选择一个图片文件,并拖放到网页中指定区域,图片缩略图将显示到网页上

copy code
<div id="targetArea" style="height:50px;line-height:50px;width:210px;background:lightblue;">请将图片文件拖放到该区域内</div>
<div id="result"></div>
<script>
function addEvent(target,type,handler){
    if(target.addEventListener){
        target.addEventListener(type,handler,false);
    }else{
        target.attachEvent('on'+type,function(event){
            return handler.call(target,event);
        });
    }
}
function preventDefault(e){
    e = e || event;
    if(e.preventDefault){
        e.preventDefault();
    }else{
        e.returnValue = false;
    }
}
addEvent(document,'dragover',preventDefault);
addEvent(document,'drop',preventDefault);
addEvent(targetArea,'dragenter',preventDefault);
addEvent(targetArea,'dragover',preventDefault);
addEvent(targetArea,'dragleave',preventDefault);
addEvent(targetArea,'drop',preventDefault);
targetArea.ondragenter = function(e){this.style.outline = "1px solid black";}
targetArea.ondragleave = function(e){this.style.outline = "";}
targetArea.ondrop = function(e){
    e = e || event;
    this.style.outline = "";
    var file = e.dataTransfer.files[0];
    if(file){
        //一张图片被选中
        if (/image/.test(file.type)){
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = function(){
                var oDiv = document.createElement('div');
                oDiv.id = file.name.split('.').join('_')
                var img = new Image();
                img.src = reader.result;
                img.height = 60;
                var oName = document.createElement('span');
                oName.innerHTML = file.name;
                var oDel = document.createElement('button');
                oDel.innerHTML = '删除';
                oDel.onclick = function(){
                    result.removeChild(oDiv);
                }               
                oDiv.appendChild(img);
                oDiv.appendChild(oName);
                oDiv.appendChild(oDel);
                result.appendChild(oDiv);
            }
        //其他格式文件被选中
        } else {
            alert("You must select a valid image file!");
        }          
    }
}
</script>
copy code

 

文件进度

  使用onprogress事件的loaded和total属性,可以实现文件进度显示

copy code
<input id="file1" type="file"  style="display:none">
<button id="btn">选择文件</button>
<div id="fileData"></div>
<script>
btn.onclick = function(){file1.click();}
file1.onchange = function(){
    var file = file1.files[0];
    //如果一个文件被选中
    if(file){
        var reader = new FileReader();
        reader.readAsText(file);
        reader.onprogress = function(e){
            e = e || event;
            fileData.innerHTML = '文件进度为:' + e.loaded + '/' + e.total;
        }
    }         
}
</script>
copy code

 

文件上传

方法一:使用表单提交实现文件上传

  文件上传最基本的方法是使用HTML表单选择本地文件进行上传,在form表单中通过<input type="file">标记选择本地文件。并且,必须在<form>元素中将enctype设置为"multipart/form-data",将method设置为"post"

  另外,需要在<form>表单中设置一个hidden类型的input框,其中name值为MAX_FILE_SIZE的隐藏值域,通过设置其value值限制上传文件的大小

<form action="pp.php" method="post" enctype="multipart/form-data">
    <input type="hidden" name="MAX_FILE_SIZE" value="1000000">
    <input type="file" name="file1">
    <button>上传文件</button>
</form>

方法二:使用FormData实现文件上传

  创建一个FormData()对象,通过它调用append()方法并传入相应的File对象作为参数。然后,再把FormData对象传递给XHR的send()方法

  [注意]IE9-浏览器不支持使用FormData()上传文件

copy code
<input type="file" name="file1" id="file1">
<div id="result"></div>
<script>
var oFile = document.getElementById('file1');
oFile.onchange = function(e){
    //创建xhr对象
    var xhr;
    if(window.XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }else{
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    };
    var data = new FormData();
    data.append('file',oFile.files[0])
    //异步接受响应
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                //实际操作
                result.innerHTML = xhr.responseText;
            }
        }
    }
    //发送请求
    xhr.open('post','pp.php',true);
    xhr.send(data);
}
</script>
copy code

方法三:使用File API实现文件上传

  通过File API传送二进制文件

  [注意]IE9-浏览器不支持

copy code
<input type="file" name="file1" id="file1">
<div id="result"></div>
<script>
var oFile = document.getElementById('file1');
oFile.onchange = function(e){
    //创建xhr对象
    var xhr;
    if(window.XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }else{
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    };
    var data = oFile.files[0];
    //异步接受响应
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                //实际操作
                result.innerHTML = xhr.responseText;
            }
        }
    }
    //发送请求
    xhr.open('post','pp.php',true);
    xhr.setRequestHeader("content-type",data.type);
    xhr.send(data);
}
</script>
copy code
copy code
<?php
$file = 'photo/test1.jpg';
touch($file);

function binary_to_file($file){
    $content = $GLOBALS['HTTP_RAW_POST_DATA'];  // 需要php.ini设置
    if(empty($content)){
        $content = file_get_contents('php://input'); //不需要php.ini设置,内存压力小
    }
    $ret = file_put_contents($file, $content, true);
    return $ret;
};echo '文件上传成功!';
?>
copy code

 

删除文件

  Finally, a small knowledge point, how to delete a file after using the <input type="file> control to select a file? Generally, there are two methods. One is to use the reset() method of the form form to reset the form; The other is to empty the value of the <input type="file> control, but the second method IE10-browser does not support

copy code
<form id="myForm">
  <input type="file" id="myFile">
</form>
<button id="btn1">Delete file method 1</button>
<button id="btn2">Delete file method 2</button>
<script>
var myFile = document.getElementById('myFile');
var myForm = document.getElementById('myForm');
btn1.onclick = function(){
  myFile.value = '';
}
btn2.onclick = function(){
  myForm.reset();
}
</script>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324813256&siteId=291194637