📜 ⬆️ ⬇️

Features of uploading files to HTML5

After some experience, I decided to write a small article-cheat sheet on uploading files using HTML5 features, namely File API.

Read on:
  1. Browser support.
  2. Download via Form Data.
  3. Download via File Reader.


1. Browser support


Of course, not all browsers currently fully support this feature. We safely forget about IE, as it will only support File API in version 10. With the other, more advanced browsers, and this is just Chrome, Firefox, Opera and Safari, everything is not so smooth either. Of course, they are trying to be "first", but not everyone is able to do it yet.

In HTML 5, there are 2 ways to read and asynchronously send a file to the server: via File Reader and Form Data objects. In principle, it is precisely for downloading files that there is no difference in which way to send files to the server. Speaking exactly, sending the files is responsible for the XMLHttpRequest object, and File Reader and Form Data only allow you to read the file and feed it to XHR. These objects are designed for different tasks. File Reader is designed to work with files on the browser side. That is, before uploading a file to the server, you can find out its parameters, such as weight, type, creation date, etc. Pictures, for example, can be immediately shown to the user without uploading them to the server. Form Data is designed to create forms and manage form data before uploading to the server. And as we know, input forms = “file” is present in the forms, through which up to this point we sent the files. Thus, you can create a form, attach a file to it and send it to the server via XHR.
')
From the lyrics to the case. Consider both boot examples. But before that, a small note that it would be nice to determine the browser's capabilities for downloading via the File API. To do this, it is enough to check for the presence of File Reader or Form Data objects. But! Safari has not yet done File Reader support and you will not be able to work with this object. Yablofagi are indignant, and we love all users equally. Therefore, at the moment, Form Data will be considered the most correct check:

if (window.FormData === undefined) { //   ,    :-)    . } 


2. Download via Form Data


First, we describe all the events: dragging and dropping files, “throwing” them into a block for downloading, etc.

 $("#drop-block").bind( // #drop-block        'dragenter', function(e) { //        . }) .bind( 'dragover', function(e) { //        . }).bind( 'dragleave', function(e) { //         . }).bind( 'drop', function(e) { //   «»   . if (e.originalEvent.dataTransfer.files.length) { //    -   . e.preventDefault(); e.stopPropagation(); // e.originalEvent.dataTransfer.files —     . // e.originalEvent.dataTransfer.files[i].size —     . // e.originalEvent.dataTransfer.files[i].name —   . //    :-) upload(e.originalEvent.dataTransfer.files); //   . } }); 

Well, the code directly reading and downloading files:

 function upload(files) { //       . //    ,   Safari   //  . $.get('/blank.html'); var http = new XMLHttpRequest(); //   XHR,       . //   if (http.upload && http.upload.addEventListener) { http.upload.addEventListener( //      . 'progress', function(e) { if (e.lengthComputable) { // e.loaded —   . // e.total —     . //    —   - :-) } }, false ); http.onreadystatechange = function () { //     if (this.readyState == 4) { //   4 ,    4        if(this.status == 200) { //     //    . // ,  // var result = $.parseJSON(this.response); //       . } else { //       . } } }; http.upload.addEventListener( 'load', function(e) { //         . //       . //  . }); http.upload.addEventListener( 'error', function(e) { // ,   ! }); } var form = new FormData(); //   . form.append('path', '/'); //   . for (var i = 0; i < files.length; i++) { form.append('file[]', files[i]); //      . } http.open('POST', '/upload.php'); //    . http.send(form); //   ,    .  XHR. } 


3. Download via File Reader


File Reader itself is designed to work with files on the browser side. Let's try to upload files using this object. We remind you that in Safari there is no File Reader object!

 if (window.FileReader === undefined) { //      //   — ! } //        . //        ,  . //  ... var dropbox = $('#file-drag'); dropbox[0].ondragover = function() { return false; }; dropbox[0].ondragleave = function() { return false; }; dropbox[0].ondrop = function(e) { var files = e.dataTransfer.files; uploadFile(files[i]); e.preventDefault(); e.stopPropagation(); return false; }; //     . // -,    0   . // -,       . //     function uploadFile(file) { var reader = new FileReader(); reader.onload = function() { var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress-bar", function(e) { if (e.lengthComputable) { // -,  ;-) } }, false); //    load  error xhr.onreadystatechange = function () { if (this.readyState == 4) { if(this.status == 200) { } else { //  :-( } } }; xhr.open("POST", "upload.php"); //       ,     . var boundary = "xxxxxxxxx"; //  . xhr.setRequestHeader('Content-type', 'multipart/form-data; boundary="' + boundary + '"'); xhr.setRequestHeader('Cache-Control', 'no-cache'); //   . var body = "--" + boundary + "\r\n"; body += "Content-Disposition: form-data; name='superfile'; filename='" + unescape( encodeURIComponent(file.name)) + "'\r\n"; // unescape        . body += "Content-Type: application/octet-stream\r\n\r\n"; body += reader.result + "\r\n"; body += "--" + boundary + "--"; //     Chrome,       . if (!XMLHttpRequest.prototype.sendAsBinary) { XMLHttpRequest.prototype.sendAsBinary = function(datastr) { function byteValue(x) { return x.charCodeAt(0) & 0xff; } var ords = Array.prototype.map.call(datastr, byteValue); var ui8a = new Uint8Array(ords); this.send(ui8a.buffer); } } //  . if(xhr.sendAsBinary) { //   Firefox xhr.sendAsBinary(body); } else { //   (    W3C) xhr.send(body); } }; //   reader.readAsBinaryString(file); }; 


This article is not a guide to use, but only a tool for exploring the possibilities of HTML 5. The code does not claim to be ideal. I would be glad if someone complements or corrects.

Source: https://habr.com/ru/post/154097/


All Articles