JavaScript File API for File upload preview and api File Upload

Source: Internet
Author: User

JavaScript File API for File upload preview and api File Upload

I. Overview
In the past, accessing local files is a headache for browser-based applications. Despite the continuous development of Web 2.0 application technology, JavaScript is playing an increasingly important role, but for security reasons, JavaScript has been unable to access local files. Therefore, in order to implement functions such as drag and drop and upload local files in a browser, we have to turn to the various technologies provided by a specific browser. For example, for IE, we need to use ActiveX controls to obtain access to local files. For Firefox, we also need to use plug-ins for development. Because different browsers have different technical implementations, in order to allow programs to support multiple browsers, our programs become very complex and difficult to maintain. But now, all this has been completely changed because of the emergence of File APIs.

File API is a draft submitted by Mozilla to W3C. It aims to introduce a set of standard JavaScript APIs. Its basic function is to use JavaScript to operate on local files. For security reasons, this API only provides limited access to local files. With it, we can easily use pure JavaScript to read and upload local files. Currently, FireFox 3.6 is the first browser to support this function. In addition, the latest version of Google Chrome and Safari also have corresponding support. The File API is expected to become part of the future HTML 5 specification currently being developed by W3C.

Ii. File API Overview
The File API consists of a set of JavaScript objects and events. Grant operations to developers in <input type = "file "... /> File selection control. Figure 1 shows the combination of all the JavaScript codes of the File API.


FileList contains a set of File objects. Generally, the FileList object can be retrieved from the file field (<input type = "file".../>) in the form. Blob objects represent a group of original binary streams that the browser can read. In the Blob object, the attribute size indicates the stream size. The function slice () can split a long Blob Object into small pieces. The File object inherits from the Blob Object and adds File-related attributes to the Blob Object. The attribute name indicates the file name. This name removes the file path information and only keeps the file name. The property type indicates the MIME type of the file. The urn attribute indicates the URN information of the file. To complete File read operations, a FileReader object instance is associated with a File or Blob Object, and provides three different File read functions and six events.

Specific content of the file reading function:
ReadAsBinaryString ()Reads the file content and returns a binary string. Each byte in the file is represented as an integer in the range [0 .. 255. The function accepts a File object as a parameter.
ReadAsText ()Reads the file content and returns a string of text that represents the file content. The function accepts a File object and text encoding name as the parameter.
ReadAsDataURLReads the file content and returns a data: URL. DataURL is defined by RFC2397.
File Read event details:
Event name Event Description
OnloadstartTriggered when File Reading starts.
SSTimed trigger when reading is in progress. The event parameter contains the total amount of data read.
AbortTriggered when the read is aborted.
ErrorTriggered when a read error occurs.
LoadTriggered when the read is successful.
LoadendWhen the read is complete, both success and failure are triggered.

Iii. Simple Example of File API
Next we will use a simple example to demonstrate the basic usage of the File API. This example contains two code files. index.html contains the HTML code on the Web Side and JavaScript code for processing uploads. upload. jsp contains the code for receiving uploaded files on the server side. See sourcecode.zip in the attachment. In this example, we will display a traditional form with a File selection field. When you select a File and click Submit, we use the File API to read the File content and use the XMLHttpRequest object to upload the File to the server in Ajax mode. Figure 2 shows the running demo.


The code is gradually displayed. Listing 1 shows the HTML part of the code.
The HTML section of the sample code in Listing 1

<body>
 <h1> File API Demo </ h1>
 <p>
 <!-Form element for file upload->
 <form name = "demoForm" id = "demoForm" method = "post" enctype = "multipart / form-data"
 action = "javascript: uploadAndSubmit ();">
 <p> Upload File: <input type = "file" name = "file" /> </ p>
 <p> <input type = "submit" value = "Submit" /> </ p>
 </ form>
 <div> Progessing (in Bytes): <span id = "bytesRead">
 </ span> / <span id = "bytesTotal"> </ span>
 </ div>
 </ p>
 </ body>
As you can see, we use a normal <form> tag to include a traditional <input type = ”file”… /> element. There is also a submit element in <form>. There are <span> elements outside the <form> to indicate the amount of data read and total. The <form> action attribute points to a JavaScript function uploadAndSubmit (). This function completes the process of reading a file and uploading it. The function code is shown in Listing 2.
Listing 2 JavaScript function to read a file and upload

 function uploadAndSubmit () {
 var form = document.forms ["demoForm"];
  
 if (form ["file"]. files.length> 0) {
 // Look for <input type = "file" ... /> tags in form fields
 var file = form ["file"]. files [0];
 // try sending
 var reader = new FileReader ();

 reader.onloadstart = function () {
 // This event is triggered at the start of the read
 console.log ("onloadstart");
 document.getElementById ("bytesTotal"). textContent = file.size;
 }
 reader.onprogress = function (p) {
 // This event is triggered periodically during reading
 console.log ("onprogress");
 document.getElementById ("bytesRead"). textContent = p.loaded;
 }

 reader.onload = function () {
  // This event is triggered after the read is successfully completed
 console.log ("load complete");
 }

 reader.onloadend = function () {
  // This event will be triggered after the read is completed, regardless of success or failure
 if (reader.error) {
 console.log (reader.error);
 } else {
 document.getElementById ("bytesRead"). textContent = file.size;
 // Construct XMLHttpRequest object and send file Binary data
 var xhr = new XMLHttpRequest ();
 xhr.open (/ * method * / "POST",
 / * target url * / "upload.jsp? fileName =" + file.name
 / *, async, default to true * /);
 xhr.overrideMimeType ("application / octet-stream");
 xhr.sendAsBinary (reader.result);
 xhr.onreadystatechange = function () {
 if (xhr.readyState == 4) {
 if (xhr.status == 200) {
 console.log ("upload complete");
 console.log ("response:" + xhr.responseText);
 }
 }
 }
 }
 }

 reader.readAsBinaryString (file);
 } else {
 alert ("Please choose a file.");
 }
 }

In this function, first we find the <form> containing the <input type = ”file”… /> element, and find the <input> element containing the information of the uploaded file. If there is no file in the <input> element, the user has not selected any file, and an error will be reported at this time.
Listing 3 finds the <input> element

 var form = document.forms ["demoForm"];

 if (form ["file"]. files.length> 0)
 {
 var file = form ["file"]. files [0];
...
 }
 else
 {
 alert ("Please choose a file.");
 }

Here, the type of object returned from form ["file"]. Files is the FileList mentioned. We take the first element from it. After that, we construct the FileReader object:
 var reader = new FileReader ();
When the onloadstart event fires, the <span> element on the page that represents the total amount of data read is populated. See Listing 4
Listing 4 onloadstart event

 reader.onloadstart = function ()
 {
 console.log ("onloadstart");
 document.getElementById ("bytesTotal"). textContent = file.size;
 }
A <span> element that updates the amount of data read on the page when the onprogress event fires. See Listing 5
Listing 5 onprogress event
 reader.onprogress = function (p) {
 console.log ("onloadstart");
 document.getElementById ("bytesRead"). textContent = p.loaded;
 }
In the final onloadend event, if there are no errors, we will read the file content and upload it via XMLHttpRequest.
Listing 6 onloadend event

 reader.onloadend = function ()
 {
 if (reader.error)
 {
 console.log (reader.error);
 }
 else
 {
 // Construct XMLHttpRequest object and send file Binary data
 var xhr = new XMLHttpRequest ();
 xhr.open (/ * method * / "POST",
 / * target url * / "upload.jsp? fileName =" + file.name
 / *, async, default to true * /);
 xhr.overrideMimeType ("application / octet-stream");
 xhr.sendAsBinary (reader.result);
...
 }
 }
According to the File API specification, we can also split the processing of the event onloadend into the processing of the event error and the event load.
In this example, we use a JSP in the background to handle uploads. The JSP code is shown in Listing 7.
Listing 7 JSP code to handle uploads

 <% @ page import = "java.io. *"%> <%
  BufferedInputStream fileIn = new
 BufferedInputStream (request.getInputStream ());
  String fn = request.getParameter ("fileName");
  
  byte [] buf = new byte [1024];
// Receive file upload and save to d: \
  File file = new File ("d: /" + fn);
  
  BufferedOutputStream fileOut = new BufferedOutputStream (new
 FileOutputStream (file));
  
  while (true) {
    // read data
   int bytesIn = fileIn.read (buf, 0, 1024);
   
   System.out.println (bytesIn);
   
   if (bytesIn == -1)
 {
     break;
   }
 else
 {
     fileOut.write (buf, 0, bytesIn);
   }
  }
  
  fileOut.flush ();
  fileOut.close ();
  
  out.print (file.getAbsolutePath ());
 %>
In this JSP code, we receive the file name and binary data from the POST request. Write the binary data to the "D: \" path of the server. And return the full path of the file. The above code can be debugged in the latest Firefox 3.6.
Fourth, use drag and drop to upload files
Earlier, we introduced how to read the content of a local file and upload it to the server through the HTML5 File API. In this way, it can meet the needs of most users. One of the disadvantages is that users can only add files one by one by clicking the "Browse" button. If you need to upload files in batches, it will cause the user experience to be unfriendly. In desktop applications, users can easily upload files by dragging with the mouse. Dragging has always been a soft underbelly of web applications, and browsers generally do not provide support for dragging. Although web programmers can implement drag effects through mouseenter, mouseover, and mouseout events, this method can only limit the scope of dragging to the browser. The good news is that HTML5 not only added the File API, but also added drag and drop support. Firefox 3.5 has already provided support for the File API and drag and drop. Below we first briefly introduce the use of drag and drop, and then use an example to explain how to upload files by drag and drop.
1.Drag Introduction
Dragging generally involves two objects: a drag source and a drag target.
Drag source: In the HTML5 draft, if an object can be dragged as a source, you need to set the draggable property to true to identify that object can be used as a drag source. Then listen to the dragstart event of the source object, and set the DataTransfer in the event handler. The type and value of the drag data can be set in DataTransfer. For example, for plain text values, you can set the type to "text / plain", and url to set the type to "text / uri-list". In this way, the target object can select data according to the desired type.
Drag target: A drag target must listen to 3 events.
dragenter: The target object determines whether to receive a drag by responding to this event. If you receive, you need to cancel this event and stop the continuous propagation of time.
dragover: Display the prompting effect of dragging by responding to this event.
drop: The target object handles drag data by responding to this event. In the following example, we will get the DataTransfer object in the handler of the drop event and get the file to be uploaded.
Since this article mainly introduces the File API, this section does not explain in detail, and interested readers can refer to the HTML5 draft (see Resources).
2.Drag and upload file examples
Here is a more specific example to illustrate how to combine drag and drop and File API to upload documents. Because we interact directly with the desktop, we don't need to deal with the drag source, we can get the data directly from the DataTransfer object in the target object.
First, we need to create a target container to receive drag events, and add a div element. Then use a list to display thumbnails, progress bars and file names of uploaded files. See the HTML code in Listing 8 and in Figure 3. For the detailed code, please refer to the dnd.html file in the attachment.
Listing 8 HTML code for drag target

 <div id = "container">
 <span> Drag and drop files here to upload. </ span>
 <ul id = "fileList"> </ ul>
 </ div>
After the drag target is created, we need to listen to its corresponding events dragenter, dragover, and drop. In the dragenter event handler, we simply clear the file list and then cancel the propagation of the dragenter event, indicating that we receive the event. A more appropriate approach is to determine whether the data in DataTransfer is a file. Here we assume that all drag sources are files. In the dragover event, we cancel the event and use the default drag display effect. In the drop event we registered the handleDrop event handler to get the file information and upload the file. Listing 9 shows these event handlers.
Listing 9 Set event handler

 function addDNDListeners ()
 {
 var container = document.getElementById ("container");
 var fileList = document.getElementById ("fileList");
 // triggered when dragging into the target object
 container.addEventListener ("dragenter", function (event)
 {
 fileList.innerHTML = '';
 event.stopPropagation ();
 event.preventDefault ();
 }, false);
 // triggered when dragging on the target object
 container.addEventListener ("dragover", function (event)
 {
 event.stopPropagation ();
 event.preventDefault ();
 }, false);
 // fired when dragging ends
 container.addEventListener ("drop", handleDrop, false);
 }
 window.addEventListener ("load", addDNDListeners, false);
Handling the drop event
The user releases the mouse at the end of the drag to trigger the drop event. In the drop event, we can get the files data through the DataTransfer object of the event parameter, and we can get the information of each file by traversing the files array. Then for each file, create HTML elements to display thumbnails, progress bars, and file names. The getAsDataURL of the File object can return the contents of the file as a URL, which can be used to display thumbnails for image files. One thing to note is that in the drop event handler, you need to cancel the event's continued propagation and default handler, and end the drop event processing. Listing 10 shows the processing code for the drop event.
Listing 10 Handling of the drop event

 function handleDrop (event)
 {
  // Get the list of dragged files
 var files = event.dataTransfer.files;
 event.stopPropagation ();
 event.preventDefault ();
 var fileList = document.getElementById ("fileList");
 // Display file thumbnail, file name and upload progress, upload file
 for (var i = 0; i <files.length; i ++)
 {
 var file = files [i];
 var li = document.createElement ('li');
 var progressbar = document.createElement ('div');
 var img = document.createElement ('img');
 var name = document.createElement ('span');
 progressbar.className = "progressBar";
 img.src = files [i] .getAsDataURL ();
 img.width = 32;
 img.height = 32;
 name.innerHTML = file.name;
 li.appendChild (img);
 li.appendChild (name);
 li.appendChild (progressbar);
 fileList.appendChild (li);
 uploadFile (file, progressbar)
 }
 }
upload files
We can upload the file through the sendAsBinary method of the XMLHttpRequest object, and monitor the progress of the file upload by listening to the progress, load, and error events of the upload, successfully completing, or whether an error occurred. In the progress event handler, we determine the position of the progress bar by calculating the proportion that has been uploaded. See Listing 11. Figure 4 shows the uploaded file.
Listing 11 uploading files

 function uploadFile (file, progressbar)
 {
 var xhr = new XMLHttpRequest ();
 var upload = xhr.upload;

 var p = document.createElement ('p');
 p.textContent = "0%";
 progressbar.appendChild (p);
 upload.progressbar = progressbar;
 // Set event processing functions related to uploading files
 upload.addEventListener ("progress", uploadProgress, false);
 upload.addEventListener ("load", uploadSucceed, false);
 upload.addEventListener ("error", uploadError, false);
 // upload files
 xhr.open ("POST", "upload.jsp? fileName =" + file.name);
 xhr.overrideMimeType ("application / octet-stream");
 xhr.sendAsBinary (file.getAsBinary ());
 }
 function uploadProgress (event)
 {
 if (event.lengthComputable)
 {
  // convert progress to percentage
 var percentage = Math.round ((event.loaded * 100) / event.total);
 console.log ("percentage:" + percentage);
 if (percentage <100)
 {
 event.target.progressbar.firstChild.style.width = (percentage * 2) + "px";
 event.target.progressbar.firstChild.textContent = percentage + "%";
 }
 }
 }
 function uploadSucceed (event)
 {
 event.target.progressbar.firstChild.style.width = "200px";
 event.target.progressbar.firstChild.textContent = "100%";
 }
 function uploadError (error)
 {
 alert ("error:" + error);
 }


In this article, through the explanation of the File API specification, and two examples showing how to use it, we reveal in advance the full picture of the JavaScript File API as an important part of future HTML5. Using it, combined with other new features of HTML5, such as Drag & Drop, we can use pure JavaScript solutions to provide users with a better web application experience. At the same time, such a unified solution also allows us to avoid previous cross-browser support Great price. It is believed that the emergence and widespread application of the File API will be the general trend of Web 2.0 applications in the future.

Articles you may be interested in:
jQuery plugin jcrop + Fileapi perfect code upload, crop and preview code sharing
JavaScript File API file upload preview

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.