Formulir pengunggahan file AJAX yang bagus. HTML5: Unggah File dengan Seret & Lepas Unggah Gambar seret dan lepas




Izinkan pengguna mengunggah file ke server dengan menyeretnya, misalnya, dari desktop. Dan untuk dapat menyeret banyak file sekaligus.

Larutan

Seperti yang Anda lihat dari contoh di atas, file dikirim ke server segera setelah pemilihan. Kirim mereka berdasarkan acara:

Window.onload = function()( var uploader = new qq.FileUploader(( autoUpload: false, element: document.getElementById("file-uploader"), action: "php/upload.php" )); $("# startUpload").on("klik", function()( uploader.uploadStoredFiles(); )); );

Hasil

Secara umum, plugin memiliki banyak opsi dan pengaturan, ada panggilan balik. Semua ini dijelaskan. Fineuploader sedang dalam pengembangan konstan, jadi saya sarankan mengunjungi repositori saat menautkan dan mengambil versi terbaru.

Penyesuaian dgn mode

Plugin membuat strukturnya berdasarkan kelas .qq-uploader, semua elemen dijelaskan dalam file css fileuploader.css

Pada catatan

Jika keledai dengan keras kepala menolak untuk bekerja, buka skripnya, cari baris di sana:

Varform = qq.toElement("

");

dan ubah menjadi:

Varform = qq.toElement("

");

Pertama, tentu saja, Anda perlu membuat elemen yang akan "menangkap" file tersebut. Selain itu, kami akan meletakkan tag rentang di elemen ini untuk menampilkan pesan status pemuatan dan memasukkan dengan tipe mengajukan, agar tidak membatasi pemilihan file hanya dengan drag and drop, tetapi juga untuk memungkinkan pengguna memilih file dengan mengklik area yang ditentukan ini. Bentuk akhir dari struktur seperti itu ditunjukkan di bawah ini.

Klik di sini atau seret dan lepas file untuk diunggah.

css untuk ini HTML kodenya biasa-biasa saja, kecuali untuk desain bidangnya memasukkan:

#file( lebar:100%; tinggi:100%; tampilan:blok; posisi:absolut; atas:0; kiri:0; opasitas:0,01; )

Kami juga menjelaskan dua kelas yang, ketika ditambahkan ke area "penangkapan" file, akan menandakan pengunggahan file yang berhasil atau kesalahan jika terjadi:

#drop-zone.success( background-color:#2ecc71; ) #drop-zone.error( background-color:#e74c3c; )

Sekarang kita dapat melanjutkan untuk menulis "tindakan" dari halaman kita. Pertama, mari tulis referensi variabel ke objek yang akan sering kita akses:

Var dropZone = document.getElementById("drop-zone"); var msgConteiner = document.querySelector("#drop-zone .text");

Setelah itu, kami akan menghilangkan kejadian default saat kursor memasuki area penerima file kami sebagai berikut:

Var eventClear = function (e) ( e.stopPropagation(); e.preventDefault(); ) dropZone.addEventListener("dragenter", eventClear, false); dropZone.addEventListener("dragover", eventClear, false);

DropZone.addEventListener("drop", function (e) ( if(!e.dataTransfer.files) return; e.stopPropagation(); e.preventDefault(); sendFile(e.dataTransfer.files); ), false); document.getElementById("file").addEventListener("change", function (e) ( sendFile(e.target.files); ), false);

Dalam kedua kasus tersebut, acara diakhiri dengan pemanggilan fungsi sendFile, ke mana file yang diterima dari pengguna ditransfer.

Fungsi ini bertanggung jawab untuk mentransfer file ke server. Anda dapat melihat deskripsinya di bawah ini.

Var sendFile = function(file) ( // hapus kelas status yang mungkin telah ditambahkan // jika pengguna telah mencoba memuat sesuatu dropZone.classList.remove("sukses"); dropZone.classList.remove("error") ; / / lakukan pengecekan regular expression untuk jenis file // (dalam contoh, hanya gambar yang diperbolehkan untuk diunggah) var re = /(.jpg|.jpeg|.bmp|.gif|.png)$/i; if (!re.exec(nama.file)) ( msgConteiner.innerHTML = "Format file tidak valid!"; dropZone.classList.remove("sukses"); dropZone.classList.add("error"); ) else ( var fd = new FormData( ); // buat objek formulir fd.append("upfile", file); // tambahkan file untuk mengirimkan formulir var xhr = new XMLHttpRequest(); xhr.open("POST", "./upload .php", true ); xhr.upload.onprogress = showProgress; xhr.onreadystatechange = statChange; xhr.send(fd); // kirim ke server ) )

Seperti yang mungkin Anda perhatikan, sebelum mengirim data ke server, dua peristiwa juga diatur, yang pertama bertanggung jawab untuk menampilkan kemajuan pengunduhan, dan yang kedua untuk memberi tahu hasil pengunduhan. Mereka beroperasi sebagai berikut:

Var showProgress = function(e) ( if (e.lengthComputable) ( // hitung persentase pemuatan var persen = Math.floor((e.loaded / e.total) * 100); // menampilkan persentase saat ini msgConteiner. innerHTML = " Memuat... ("+ persen +"%)"; ) ); var statChange = function (e) ( if (e.target.readyState == 4) ( // setelah selesai memproses permintaan ke server if (e.target.status == 200) ( // jika permintaan berhasil msgConteiner.innerHTML = "Unggahan berhasil diselesaikan!"; dropZone.classList.remove("error"); dropZone.classList.add("sukses"); document.getElementById("showUpFile").innerHTML = this.responseText; ) else ( // jika tidak msgConteiner.innerHTML = "Terjadi kesalahan!"; dropZone.classList.remove("sukses"); dropZone.classList.add("error"); ) ) )

Tahap terakhir adalah pemrosesan data yang diterima oleh server.

Markup ini tidak ada hubungannya secara khusus dengan drag and drop. Ini hanya normal, fungsional

, meskipun dengan beberapa elemen HTML tambahan untuk status potensial.

Selesai!
kesalahan! .

Kami akan menyembunyikan status tersebut sampai kami membutuhkannya:

Box__dragndrop, .box__uploading, .box__success, .box__error ( display: none; )

Sedikit penjelasan:

  • Mengenai status: elemen .box__uploading akan terlihat selama proses upload file Ajax (dan yang lainnya masih akan disembunyikan). Kemudian .box__success atau .box__error akan ditampilkan tergantung pada apa yang terjadi.
  • input dan label adalah bagian fungsional dari formulir. Saya menulis tentang menata ini bersama-sama dalam posting saya tentang menyesuaikan input file. Di postingan itu saya juga menjelaskan tujuan dari atribut. Masukan dan label juga berfungsi sebagai alternatif untuk memilih file dengan cara standar (atau satu-satunya cara jika seret dan lepas tidak didukung).
  • .box__dragndrop akan ditampilkan jika browser mendukung fungsi upload file drag and drop.

Deteksi fitur

Kami tidak dapat 100% mengandalkan browser yang mendukung seret dan lepas. Kami harus memberikan solusi cadangan. Jadi: deteksi fitur. Pengunggahan file seret & lepas bergantung pada sejumlah API JavaScript yang berbeda, jadi kami harus memeriksa semuanya.

Mungkin dalam beberapa kasus, pengembang layanan yang harus disalahkan, tetapi seringkali masalahnya terletak pada batasan yang diberlakukan oleh browser. Pertimbangkan mengunggah file ke server.

Dalam kebanyakan kasus, Anda akan diberikan bidang standar dengan tombol untuk memilih file dari komputer Anda dan/atau bidang tempat Anda dapat memasukkan URL file yang dihosting di suatu tempat di web.

Kami tidak akan menyentuh unduhan file dari komputer lokal untuk saat ini, saya berencana untuk menerbitkan posting terpisah tentang topik ini, kami akan menganalisis unduhan dari server jarak jauh.

Masalah dimulai dengan langkah pertama. Bahkan jika Anda memahami dengan jelas di mana mencari URL dan pandai menggunakan alat seperti pembakar, masih perlu beberapa klik mouse untuk mendapatkan alamat yang benar. Akan jauh lebih mudah untuk hanya menyeret gambar yang diinginkan dari satu jendela browser ke jendela browser lainnya.

Saya akan menunjukkan penerapan antarmuka seperti itu di artikel ini. Jika mau, Anda dapat melihat cara kerjanya di halaman demo atau mengunduh arsip sumber.

Catatan! Contoh ini hanya berfungsi di browser Google Chrome. Secara teori, dukungan untuk semua teknologi yang diperlukan ada di Firefox dan Safari, tetapi saya belum membahasnya.

Sebagai objek untuk "menyeret", saya mengambil sebagian besar gambar dari Wikipedia. Beberapa masalah diperhatikan terkait dengan karakter non-Latin di URL gambar, tetapi agar tidak membebani contoh dengan pemeriksaan dan transformasi, saya membiarkannya apa adanya.


Prinsip operasi

Standar HTML5 menyediakan dukungan untuk "menyeret" objek halaman ( Seret dan Lepas). Omong-omong, saya telah menunjukkan contoh penerapan D&D yang paling sederhana - Seret dan jatuhkan menggunakan HTML5. Selain itu, ada beberapa pustaka JavaScript yang mengimplementasikan dukungan D&D.

Tetapi di sini penting untuk dipahami bahwa jika Anda perlu "menyeret" gambar dari sumber pihak ketiga, Anda tidak akan dapat menggunakan perpustakaan. Karena Anda tidak akan dapat menambahkan kode JS Anda ke halaman orang lain. Dan untuk mengunggah gambar, kita perlu mendapatkan URL-nya, yaitu. browser harus meneruskan parameternya dengan objek yang diseret (misalnya, atribut src dari gambar atau seluruh tag img).

Dalam hal ini, kita dapat membuat "penerima" gambar di halaman kita. Ini akan menjadi div reguler yang memiliki event handler drop yang ditugaskan padanya. Jika pengguna "menjatuhkan" gambar di atas div ini, maka penangan akan dipanggil dan pada parameter pertama dia akan menerima objek yang berisi informasi tentang gambar yang sedang diseret.

Penerapan

Mari kita mulai dengan halaman aplikasi kita.





Unggah Gambar








Ini berisi dua blok: gambar - di sini kami akan menampilkan gambar yang diunggah dan img_target - Anda perlu menyeret gambar ke blok ini.

Di bagian bawah halaman, kami menyertakan pustaka jQuery dan skrip main.js, yang akan mengirimkan informasi tentang gambar yang diseret ke server.

Pertimbangkan main.js

$(fungsi() (
$("#img_target")
.bind("dragent", function(event) (
$(ini).addClass("jatuhkan_di sini");
kembali salah;
})
.bind("dragleave", function(event) (
kembali salah;
})
.bind("dragover", function(event) (
kembali salah;
})
.bind("jatuhkan", fungsi(acara) (
$(ini).removeClass("drop_here");
var srcRegex = /src=\"([^\s]+)\"/ig;
var data = event.originalEvent.dataTransfer.getData("text/html");
var img_data = srcRegex.exec(data);
$.post("upload.php", ("file_url":img_data), function(res) (
var respon = eval("(" + res + ")");
$("#gambar").tambahkan($(" "));
});
kembali benar;
});

Di sini kami menetapkan penangan ke acara dragenter, dragleave, dan dragover. Semuanya harus mengembalikan false dan, untuk memberi tahu pengguna bahwa mungkin untuk "menjatuhkan" gambar, kami menetapkan kelas CSS drop_here untuk blok penerima di penangan dragenter.

Sebagian besar pekerjaan dilakukan di drop event handler. Saat peristiwa ini terjadi, kami membaca informasi tentang objek yang "dijatuhkan" dan "memotong" nilai atribut src, mis. URL gambar (baris 16-18). Informasi ditransfer dalam objek event.originalEvent.dataTransfer (baris 17).

Kemudian kami membentuk permintaan AJAX biasa dan mengirimkan URL yang ditemukan sebagai parameter.

Skrip server (upload.php) akan mendapatkan URL gambar di server jauh dan mengunggahnya. Dan sebagai tanggapan atas permintaan AJAX, itu akan mengirimkan URL baru dari gambar yang diunggah.

Pada gilirannya, penangan permintaan AJAX akan membuat tag img dan memasukkannya ke dalam blok gambar. Dengan demikian, gambar yang diunggah akan muncul di atas bidang unggahan.

Pertimbangkan upload.php

define("BASE_URL", "http://localhost/tests/images-upload/");

fungsi unggah_dari_url($file_url) (
$url_segmen = meledak("/", $file_url);
$file_name = urldecode(end($url_segments));
jika (salah !== $file_name) (
$file_name_parts = meledak(".", $file_name);
if (in_array(strtolower(end($file_name_parts)), array("jpeg","jpg","png","gif"))) (
$destination=fopen("upload/".$nama_berkas,"w");
$sumber=fopen($file_url,"r");
$ukuranmaksimal=300*1024;
$panjang=0;
while (($a=fread($sumber,1024))&&($panjang<$maxsize)) {
$panjang=$panjang+1024;
fwrite($tujuan,$a);
}
fclose($sumber);
fclose($tujuan);
}
}
$new_file_url = BASE_URL."upload/".$nama_file;
kembalikan $new_file_url;
}

$res = array("err" => "Tidak ada URL file yang ditentukan");

jika (isset($_POST["file_url"])) (
$new_url = upload_from_url($_POST["file_url"]);
$res = array("file_url" => $new_url);
}

echo json_encode($res);

Prinsip operasi adalah sebagai berikut. Kami membaca URL gambar dan mencoba mengunduhnya (baris 29-32).

Jika gambar diunggah, simpan ke folder unggah. Mendapatkan gambar dari server jarak jauh dilakukan dengan menggunakan fungsi fread. File dibaca dalam blok 1kB (baris 15-18). Pendekatan ini memungkinkan Anda menghentikan pengunduhan file jika ukurannya melebihi batas yang ditentukan (dalam hal ini, 300 kB).

Setelah mengunduh file, kami membuat URL untuknya dan mengirimkannya ke browser dalam format JSON.

Seperti yang Anda lihat, mengimplementasikan loader seperti itu mudah. Dan cukup nyaman untuk menggunakannya. Secara alami, kelemahan utamanya adalah dukungan HTML5 oleh browser, atau lebih tepatnya tidak ada.

Namun, jika Anda membuat antarmuka untuk karyawan beberapa perusahaan, dan Anda dapat menentukan jenis browser, maka HTML5 dapat digunakan.

Dalam tutorial ini, saya akan menunjukkan kepada Anda contoh pengintegrasian plugin Dropzone.js yang luar biasa dengan situs php Anda untuk mengunggah file ke server hanya dalam beberapa baris kode.

Dropzone.JS adalah perpustakaan sumber terbuka yang luar biasa yang ditulis dalam vanilla JS yang memberi Anda antarmuka pengunggahan file seret dan lepas dengan pratinjau file.

Untuk memulai, unduh versi terbaru pustaka dan gayanya:

Kemudian buat folder upload dan file index.php dan upload.php

Bagian dari kode Anda yang berisi formulir untuk menambahkan materi ke situs dapat berfungsi sebagai file indeks php. Dalam contoh saya, saya akan membuat halaman bersih dengan markup minimal dan pustaka serta gaya Dropzone.js yang disertakan:

Seperti yang mungkin Anda perhatikan, kami membuat formulir dengan tindakan upload.php, tetapi kami tidak membuat input unggahan file apa pun, dan kami tidak mendeklarasikan enctype formulir. Tidak ada kesalahan dalam hal ini, semuanya ditangani oleh pustaka DropzoneJS itu sendiri. Yang perlu kita lakukan adalah memberikan bentuk kelas dropzone. Secara default, DropzoneJS menemukan semua bentuk dengan kelas yang diberikan dan secara otomatis merender antarmukanya.

Anda dapat membuka halaman index.php di browser dan memverifikasi bahwa perpustakaan berfungsi sebagaimana mestinya. Inilah yang saya dapatkan:

Sekarang mari buat penangan upload yang file upload.php-nya sudah kita buat. Berikut adalah contoh kode pemuatan saya yang paling sederhana:

Bekerja dengan file yang diunggah

Untuk interaksi penuh dengan file Anda, kami hanya perlu menambahkan kemampuan untuk memanipulasinya. Pertama kita perlu menambahkan cuplikan kode untuk mengambil informasi tentang file yang disimpan (nama dan ukuran) dan mengembalikannya dalam format JSON.

Untuk melakukannya, perbarui file upload.php ke formulir ini (kondisi lain dimasukkan):

  1. Fungsi scandir PHP memindai folder unggahan dan mengembalikan array file, atau FALSE jika folder tersebut kosong.
  2. Ulangi nilai kembalian dari fungsi scandir dan simpan dalam array $result. Ingat, kita abaikan "." Dan ".." karena scandir akan selalu mengembalikan "." Dan ".." sebagai konten yang valid, mengacu pada direktori saat ini dan sebelumnya.
  3. Kami menampilkan header yang benar untuk markup JSON, dan juga mengonversi larik PHP menjadi string JSON menggunakan fungsi json_encode.

Sekarang saatnya memperbarui index.php:

Apa yang telah kita lakukan di sini? Mari kita cari tahu:

  1. Sayangnya dan ah, kami telah menambahkan perpustakaan Jquery ke halaman kami. Ini tidak terlalu diperlukan untuk DropzoneJs. Kami hanya menggunakan fungsi JQuery $.get ajax. Anda, atas kebijaksanaan Anda, dapat mengimplementasikan permintaan tersebut di vue.js atau apa pun yang Anda inginkan.
  2. Kami telah menambahkan elemen ID (my-dropzone) ke formulir. Ini diperlukan untuk meneruskan nilai konfigurasi ke Dropzone. Dan untuk ini kita harus memiliki pengidentifikasi unik yang menunjuk ke sana. Dengan cara ini kami dapat menyesuaikan perpustakaan dengan menetapkan nilai ke Dropzone.options.myDropzone.
  3. Kami menginisialisasi bagian utama pengeditan. Apa yang telah kita lakukan di sini adalah meneruskan fungsi untuk mendengarkan acara init Dropzone. Acara ini dipicu saat Dropzone diinisialisasi.
  4. Kami mendapatkan berbagai file dari "upload.php" menggunakan ajax.
  5. Kami membuat mockFile menggunakan nilai dari server. MockFiles hanyalah objek JavaScript dengan properti nama dan ukuran. Kami kemudian secara eksplisit memanggil fungsi Dropbox dan menambahkan ikon untuk menempatkan file yang ada di area unggahan Dropzone dan membuat thumbnail-nya.

Jika Anda melakukan segalanya dengan benar. Unggah beberapa gambar dan muat ulang halaman formulir. File yang diunggah sebelumnya akan muncul secara otomatis di area Dropzone.