Kịch bản đẹp để tải lên hình ảnh. Ajax và PHP. Tải hình ảnh lên máy chủ

Tải tập tin hoặc hình ảnh lên máy chủ là một công việc khá điển hình. Nhưng tiến trình không đứng yên, và do đó, tất nhiên, bây giờ tôi muốn các tệp được tải xuống ở lý lịch. Theo quy định, trước đây điều này có thể được thực hiện bằng cách sử dụng công nghệ đèn flash hoặc khung nội tuyến. Ngoài ra, nhiều người sử dụng các plugin như jQuery Form Plugin hoặc Ajax File Upload Plugin hoặc Multiple File Upload Plugin và rất nhiều plugin khác. Với sự ra đời của đối tượng FormData, mọi thứ đã trở nên đơn giản hơn nhiều. FormData() cho phép bạn soạn một tập hợp dữ liệu để gửi đến máy chủ bằng XMLHttpRequest.

Chúng ta hãy thử viết mã của riêng mình mà không cần bất kỳ plugin nào (tất nhiên, ngoại trừ khung jQuery) để tải hình ảnh hoặc tệp lên máy chủ ở chế độ nền. Nói chung, thuật toán hành động của chúng tôi sẽ giống như thế này: điền dữ liệu vào các trường biểu mẫu. Các trường có thể là bất cứ thứ gì, văn bản, vùng văn bản, vùng chọn và tệp. Khi bạn chọn tệp, nhờ mã jQuery của chúng tôi, các tệp này sẽ được tải xuống ở chế độ nền vào một thư mục tạm thời trên máy chủ, ví dụ như “tmp”. Tiếp theo, khi nhấn nút gửi biểu mẫu, dữ liệu sẽ được gửi đến tập lệnh máy chủ sẽ xử lý dữ liệu. Hãy tưởng tượng rằng đây là những bài viết. Chúng tôi sẽ ghi lại dữ liệu được truyền vào cơ sở dữ liệu với một id duy nhất. Tiếp theo, chúng tôi sẽ tạo một thư mục trong thư mục “hình ảnh” với số “id” duy nhất và nếu chúng tôi có bất kỳ tệp nào trong thư mục “tmp”, chúng tôi sẽ sao chép chúng vào thư mục “id” đã tạo và sau đó xóa “tmp” " thư mục. Tóm lại: chúng ta điền hình ảnh vào tmp làm nền, khi submit form chúng ta ghi dữ liệu vào cơ sở dữ liệu sẽ có một số bản ghi duy nhất. Chúng tôi tạo một thư mục có số này và di chuyển các tệp của chúng tôi đến đó. Tất cả. Trong bài viết này, chúng tôi sẽ không xem xét việc tải lên cơ sở dữ liệu và sao chép tệp. Tôi nghĩ sẽ có điều gì đó dành cho mọi người ở đây. Chúng tôi sẽ tập trung vào một điều - tải không đồng bộ hình ảnh (hoặc tập tin).

Vì vậy, đây là phần html của chúng tôi. Ở đây chúng ta sẽ chú ý đến thực tế là chúng ta có một tệp GIF có hình ảnh của trình tải trước (vòng tròn lặp), mà chúng ta ẩn khỏi hiển thị bằng các kiểu. Chúng ta cũng sẽ gán id = file cho trường file và enctype = “multipart/form-data” cho form. Tên trường tệp sẽ là tệp, tức là. để chúng ta có thể làm việc với mảng, vì chúng ta được phép tải lên nhiều tệp (nhiều thuộc tính).

#preloader (khả năng hiển thị: ẩn;) Thêm thông tin

Trong biểu mẫu này, ngoài trường tệp, chúng tôi có một số trường chẳng hạn: input=text. Những thứ kia. Trước mắt chúng tôi là một biểu mẫu thông thường, chẳng hạn như dành cho bảng quản trị, đây là tập hợp các trường bạn cần. Để bắt đầu, nếu muốn, bạn có thể kiểm tra hoạt động của tập lệnh bằng cách viết các dòng hiển thị mảng FILES ở đầu tệp:

//upload.php print_r($_FILES);

Bây giờ hãy viết tập lệnh máy chủ của chúng ta, tập lệnh này sẽ được gọi từ sử dụng jQuery. Nhiệm vụ của nó là chuyển các tệp đã tải lên từ thư mục tạm thời của máy chủ sang thư mục của chúng tôi, chẳng hạn như chúng tôi đã quyết định trong “tmp”, sau đó hiển thị chúng.

//upload.php function show_dir($dir) // hàm hiển thị ảnh từ thư mục tmp ( $list = scandir($dir); unset($list,$list); foreach ($list as $file) ( echo " "; ) ) foreach ($_FILES as $key => $value) ( ​​//di chuyển tệp sang tmp move_uploaded_file($value["tmp_name"], "tmp/".$value["name"]); ) show_dir( "./tmp/");

Và bây giờ là tập lệnh js của chúng tôi, tập lệnh này sẽ tải các tệp của chúng tôi lên máy chủ ở chế độ nền. Tất cả điều kỳ diệu sẽ được thực hiện nhờ đối tượng FormData(). Chúng tôi sẽ thêm mã này vào cuối index.php trước thẻ.

$(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 + " quá lớn."; ) // Kiểm tra kích thước tệp if(file.type != "image/png" && file.type != "image/jpg " " && !file.type != "image/gif" && file.type != "image/jpeg") ( error = error + "File " + file.name + " không khớp với png, jpg hoặc gif" ; ) / /Kiểm tra loại tập tin data.append("file-"+i, file); )); if (error != "") ($("#info").html(error);) else ( $.ajax(( url: "upload.php", data: data, cache: false, contentType: false, processData: false, gõ: "POST", beforeSend: function() ( $("#preloader").show(); ), thành công: function(data)( $("#info").html(data); $("#preloader").ẩn(); ) )));

Chà, có vẻ như vậy là hết rồi. Nếu có ai không hiểu điều gì, hãy hỏi. Nếu ai có bổ sung gì thì tôi cũng rất vui!
Mẹo: nếu bạn chưa sử dụng mã để xóa tệp khỏi bất kỳ thư mục nào thì tôi khuyên bạn nên thay đổi chức năng xóa rmdir thành echo để kiểm tra nhằm đảm bảo rằng chỉ những tệp bạn muốn xóa mới bị xóa. Ví dụ: trình tải trước Gif có thể được lấy từ bài học Cách tạo ảnh động Gif của tôi. Ví dụ ở cuối bài viết.

CẬP NHẬT:

Nếu ai đó muốn thêm vẻ đẹp, chẳng hạn như thanh tiến trình, thì để làm được điều này, chúng ta sẽ cần thêm một vài dòng mã. TRONG mẫu html chúng tôi sẽ thêm một siêu phần tử từ html5 - Progress và trong mã js, chúng tôi sẽ thêm một số dòng có đối tượng XMLHttpRequest.
Và vì vậy, html của chúng tôi sẽ được bổ sung những điều sau:

Và hãy thêm vào mã js:

Hàm ProgressHandlingFunction(e)( if(e.lengthComputable)( $("progress").attr((value:e.loaded,max:e.total)); ) )

Xhr: function() ( var myXhr = $.ajaxSettings.xhr(); if(myXhr.upload)( // kiểm tra xem quá trình tải lên có đang được thực hiện không myXhr.upload.addEventListener("progress",progressHandlingFunction, false); // truyền tới các giá trị hàm) trả về myXhr;

Kết quả cuối cùng của mã js:

$(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 + " quá lớn."; ) if(file.type != "image/png" && file.type != "image/jpg" && !file. type != "image/gif" && file.type != "image/jpeg") ( error = error + "File " + file.name + " không khớp với png, jpg hoặc gif"; ) data.append( "tệp -"+i, tệp); )); if (error != "") ($("#info").html(error);) else ( $.ajax(( url: "productUploadImg.php", type: "POST", xhr: function() ( var myXhr = $.ajaxSettings.xhr(); if(myXhr.upload)( // kiểm tra xem quá trình tải lên có đang diễn ra không myXhr.upload.addEventListener("progress",progressHandlingFunction, false); // truyền giá trị cho hàm ) trả về myXhr ) , data: data, cache: false, contentType: false, processData: false, beforeSend: function() ( $("#preloader").show(); ), thành công: function(data)( $( "#info" ).html(data); $("#preloader").hide(); , lỗi: errorHandler = function() ( $("#info").html("Lỗi tải tệp"); ) )); ) )) ));

Chúng ta đã tìm hiểu một số phương pháp cơ bản để truy xuất dữ liệu và chuyển dữ liệu đó bằng yêu cầu AJAX. Bây giờ là lúc nói về cách bạn có thể tải tập tin xuống từ sử dụng AJAX. Cho đến gần đây, không có nhiều cách để tải xuống tệp mà không cần tải lại trang (iframe ẩn, Flash). Chúng vẫn được sử dụng cho đến ngày nay vì vẫn có những người dùng có phiên bản trình duyệt cũ hơn không bị ảnh hưởng bởi tiến trình. Nhưng chúng tôi sẽ không nhìn lại quá khứ, vì vậy chúng tôi theo kịp thời đại.

Theo ý kiến ​​của tôi, hãy xem xét một trong những điều quan trọng nhất cách thuận tiệnđể làm việc với các tệp (và không chỉ) - đối tượng FormData. Hãy để có một hình thức đơn giản để tải hình đại diện của người dùng:

HTML ( tập tin index.html)

HỌ VÀ TÊN:
Hình đại diện:

Hãy chuyển sang phần JS. Sẽ không có khó khăn gì với trường “Tên đầy đủ” và chúng tôi chỉ sử dụng nó để minh họa rằng cùng với tệp, chúng tôi có thể gửi bất kỳ dữ liệu nào khác.

jQuery ( tập tin script.js)

$(function())( $("#my_form").on("submit", function(e)( e.preventDefault(); var $that = $(this), formData = new FormData($that.get ( 0)); // tạo một thể hiện đối tượng mới và truyền biểu mẫu của chúng ta cho nó (*) $.ajax(( url: $that.attr("action"), type: $that.attr("method"), contentType: false , // quan trọng - xóa định dạng dữ liệu mặc định processData: false, // quan trọng - xóa dữ liệu chuyển đổi chuỗi mặc định: formData, dataType: "json", thành công: function(json)( if(json)( $that .replaceWith(json);

(*)Xin lưu ý rằng chúng tôi chuyển biểu mẫu không phải dưới dạng đối tượng jQuery mà dưới dạng phần tử DOM

Trình xử lý PHP ( tập tin xử lý.php)