Beautiful script for uploading images. Ajax and PHP. Uploading an image to the server

Uploading files or pictures to a server is a fairly typical task. But progress does not stand still, and therefore now, of course, I want files to be downloaded in background. As a rule, previously this could be implemented using flash technologies or iframe. Also, many people use plugins such as jQuery Form Plugin or Ajax File Upload Plugin or Multiple File Upload Plugin and a sea of ​​others. With the advent of the FormData object, everything has become much simpler. FormData() allows you to compose a set of data to send to the server using XMLHttpRequest.

Let's try to write our own code without any plugins (well, except for the jQuery framework, of course) to upload pictures or files to the server in the background. In general, the algorithm of our actions will be something like this: fill the form fields with data. The fields can be anything, text, textarea, select and files. When you select files, thanks to our jQuery code, these files will be downloaded in the background to a temporary directory on the server, for example “tmp”. Next, when you press the button submit forms, the data is sent to a server script that will process the data. Let's imagine that these are articles. We will record the transmitted data in a database with a unique id. Next, we will create a directory in the “images” directory with a unique number “id” and if we had any files in the “tmp” folder, we will copy them to the created “id” folder and then clear the “tmp” folder. To summarize: we fill the images into tmp as a background, when submitting the form we write the data to the database, we will have a unique record number. We create a folder with this number and move our files there. All. In this article, we will not consider uploading to the database and copying files. I think there will be something for everyone here. We will focus on one thing - asynchronous loading pictures (or files).

So here is our html piece. Here we will pay attention to the fact that we have a GIF file with a picture of the preloader (looped circle), which we hide from display with styles. We will also assign id = file to the file field, and enctype = “multipart/form-data” to the form. The file field name will be file i.e. so that we can work with the array, since we are allowed to upload multiple files (multiple attribute).

#preloader (visibility: hidden;) Add information

In this form, in addition to the file field, we have a couple of fields for example: input=text. Those. Before us is a regular form, for example for the admin panel, which is a set of fields you need. To begin with, if you want, you can check the operation of the script by writing the lines showing the FILES array at the beginning of the file:

//upload.php print_r($_FILES);

Now let's write our server script, which will be called from using jQuery. Its task is to transfer the uploaded files from the server’s temporary directory to ours, for example, as we decided in “tmp”, and then display them.

//upload.php function show_dir($dir) // function for showing pictures from the tmp folder ( $list = scandir($dir); unset($list,$list); foreach ($list as $file) ( echo " "; ) ) foreach ($_FILES as $key => $value) ( ​​//move files to tmp move_uploaded_file($value["tmp_name"], "tmp/".$value["name"]); ) show_dir( "./tmp/");

And now our js script, which will upload our files to the server in the background. All the magic will be done thanks to the FormData() object. We will add this code to the end of our index.php before the tag.

$(document).ready(function())( $("#preloader").hide(); $("#file").bind("change", function())( var data = new FormData(); var error = ""; jQuery.each($("#file").files, function(i, file) ( if(file.name.length< 1) { error = error + " Файл имеет неправильный размер! "; } //Проверка на длину имени if(file.size >1000000) ( error = error + " File " + file.name + " is to big."; ) //Checking file size if(file.type != "image/png" && file.type != "image/jpg" " && !file.type != "image/gif" && file.type != "image/jpeg") ( error = error + "File " + file.name + " doesn't match png, jpg or gif"; ) / /Checking file types data.append("file-"+i, file); )); if (error != "") ($("#info").html(error);) else ( $.ajax(( url: "upload.php", data: data, cache: false, contentType: false, processData: false, type: "POST", beforeSend: function() ( $("#preloader").show(); ), success: function(data)( $("#info").html(data); $("#preloader").hide(); ) )));

Well, that seems to be all. If anyone doesn't understand something, ask. If anyone has any additions, I will be glad too!
Tip: if you have not yet used code to delete files from any directory, then I recommend changing the rmdir delete function to echo for a test to make sure that only those files that you want to delete will be deleted. Gif preloaders can be taken, for example, from my lesson How to make Gif animation. Examples at the end of the article.

UPD:

If anyone wants to add beauty, for example a progress bar, then for this we will need to add a few lines of code. IN html template we will add a super element from html5 - progress, and in the js code we will add several lines with an XMLHttpRequest object.
And so, our html will be supplemented with the following:

And let’s add to the js code:

Function progressHandlingFunction(e)( if(e.lengthComputable)( $("progress").attr((value:e.loaded,max:e.total)); ) )

Xhr: function() ( var myXhr = $.ajaxSettings.xhr(); if(myXhr.upload)( // checking that upload is being carried out myXhr.upload.addEventListener("progress",progressHandlingFunction, false); //passing to the function values ​​) return myXhr;

The final result of the js code:

$(document).ready(function())( function progressHandlingFunction(e)( if(e.lengthComputable)( $("progress").attr((value:e.loaded,max:e.total)); ) ) $("#preloader").hide(); $("#file").bind("change", function())( var data = new FormData(); var error = ""; jQuery.each($( "#file").files, function(i, file) ( if(file.name.length< 1) { error = error + " Файл имеет неправильный размер! "; } if(file.size >1000000) ( error = error + " File " + file.name + " is to big."; ) if(file.type != "image/png" && file.type != "image/jpg" && !file. type != "image/gif" && file.type != "image/jpeg") ( error = error + "File " + file.name + " doesn't match png, jpg or gif"; ) data.append("file -"+i, file); )); if (error != "") ($("#info").html(error);) else ( $.ajax(( url: "productUploadImg.php", type: "POST", xhr: function() ( var myXhr = $.ajaxSettings.xhr(); if(myXhr.upload)( // checking that upload is in progress myXhr.upload.addEventListener("progress",progressHandlingFunction, false); //passing values ​​to the function ) return myXhr ) , data: data, cache: false, contentType: false, processData: false, beforeSend: function() ( $("#preloader").show(); ), success: function(data)( $("#info" ).html(data); $("#preloader").hide(); , error: errorHandler = function() ( $("#info").html("Error loading files"); ) )); ) )) ));

We've gone over several basic methods for retrieving data and passing it on with an AJAX request. Now it's time to talk about how you can download files from using AJAX. Until recently, there were not so many ways to download files without reloading the page itself (hidden iframe, Flash). They are still used today because there are still users with older versions of browsers who have not been affected by progress. But we won’t look back, so we keep pace with the times.

Let's consider, in my opinion, one of the most convenient ways for working with files (and not only) - the FormData object. Let there be such a simple form for loading the user’s avatar:

HTML ( index.html file)

FULL NAME:
Avatar:

Let's move on to the JS part. There will be no difficulties with the “Full Name” field and we use it only to illustrate that along with the file, we can send any other data.

jQuery ( script.js file)

$(function())( $("#my_form").on("submit", function(e)( e.preventDefault(); var $that = $(this), formData = new FormData($that.get( 0)); // create a new object instance and pass our form to it (*) $.ajax(( url: $that.attr("action"), type: $that.attr("method"), contentType: false , // important - remove the default data formatting processData: false, // important - remove the default string conversion data: formData, dataType: "json", success: function(json)( if(json)( $that.replaceWith( json);

(*)Please note that we are passing the form not as a jQuery object, but as a DOM element

PHP handler ( handler.php file)