В преведущей статье был приведен пример отправки файлов через AJAX с помощью плагина «jQuery Form Plugin». Но файлы можно отправить и обычным методом jQuery $.ajax()
.
Для примера возьмем поле <input type="file">
и элемент div
с id="result"
для вывода результата.
Чтобы отправить файл нужно отправить его бинарный данные, для этого есть объект FormData, поддерживается он всеми современными браузерами.
<input type="file" id="js-file">
<div id="result">
<!-- Результат из upload.php -->
</div>
<script src="/jquery.min.js"></script>
<script>
$("#js-file").change(function(){
if (window.FormData === undefined) {
alert('В вашем браузере FormData не поддерживается')
} else {
var formData = new FormData();
formData.append('file', $("#js-file")[0].files[0]);
$.ajax({
type: "POST",
url: '/upload.php',
cache: false,
contentType: false,
processData: false,
data: formData,
dataType : 'json',
success: function(msg){
if (msg.error == '') {
$("#js-file").hide();
$('#result').html(msg.success);
} else {
$('#result').html(msg.error);
}
}
});
}
});
</script>
Помимо использования formData, в настройках $.ajax
нужно указать параметры contentType: false
и processData: false
т.к. без них файл не отправится.
Код скрипта upload.php
<?php
// Название <input type="file">
$input_name = 'file';
// Разрешенные расширения файлов.
$allow = array();
// Запрещенные расширения файлов.
$deny = array(
'phtml', 'php', 'php3', 'php4', 'php5', 'php6', 'php7', 'phps', 'cgi', 'pl', 'asp',
'aspx', 'shtml', 'shtm', 'htaccess', 'htpasswd', 'ini', 'log', 'sh', 'js', 'html',
'htm', 'css', 'sql', 'spl', 'scgi', 'fcgi', 'exe'
);
// Директория куда будут загружаться файлы.
$path = __DIR__ . '/uploads/';
$error = $success = '';
if (!isset($_FILES[$input_name])) {
$error = 'Файл не загружен.';
} else {
$file = $_FILES[$input_name];
// Проверим на ошибки загрузки.
if (!empty($file['error']) || empty($file['tmp_name'])) {
$error = 'Не удалось загрузить файл.';
} elseif ($file['tmp_name'] == 'none' || !is_uploaded_file($file['tmp_name'])) {
$error = 'Не удалось загрузить файл.';
} else {
// Оставляем в имени файла только буквы, цифры и некоторые символы.
$pattern = "[^a-zа-яё0-9,~!@#%^-_\$\?\(\)\{\}\[\]\.]";
$name = mb_eregi_replace($pattern, '-', $file['name']);
$name = mb_ereg_replace('[-]+', '-', $name);
$parts = pathinfo($name);
if (empty($name) || empty($parts['extension'])) {
$error = 'Недопустимый тип файла';
} elseif (!empty($allow) && !in_array(strtolower($parts['extension']), $allow)) {
$error = 'Недопустимый тип файла';
} elseif (!empty($deny) && in_array(strtolower($parts['extension']), $deny)) {
$error = 'Недопустимый тип файла';
} else {
// Перемещаем файл в директорию.
if (move_uploaded_file($file['tmp_name'], $path . $name)) {
// Далее можно сохранить название файла в БД и т.п.
$success = '<p style="color: green">Файл «' . $name . '» успешно загружен.</p>';
} else {
$error = 'Не удалось загрузить файл.';
}
}
}
}
// Вывод сообщения о результате загрузки.
if (!empty($error)) {
$error = '<p style="color: red">' . $error . '</p>';
}
$data = array(
'error' => $error,
'success' => $success,
);
header('Content-Type: application/json');
echo json_encode($data, JSON_UNESCAPED_UNICODE);
exit();
Пример работы:
Для одновременной загрузки файлов элементу input file
нужно добавить атрибут multiple
, также изменится добавление данных в объект formData.
<input type="file" multiple id="js-file">
<div id="result">
<!-- Результат из upload.php -->
</div>
<script src="/jquery.min.js"></script>
<script>
$("#js-file").change(function(){
if (window.FormData === undefined){
alert('В вашем браузере FormData не поддерживается')
} else {
var formData = new FormData();
$.each($("#js-file")[0].files,function(key, input){
formData.append('file[]', input);
});
$.ajax({
type: "POST",
url: '/upload.php',
cache: false,
contentType: false,
processData: false,
data: formData,
dataType : 'json',
success: function(data){
data.forEach(function(msg) {
$('#result').append(msg);
});
}
});
}
});
</script>
Код скрипта upload.php
<?php
// Название <input type="file">
$input_name = 'file';
// Разрешенные расширения файлов.
$allow = array();
// Запрещенные расширения файлов.
$deny = array(
'phtml', 'php', 'php3', 'php4', 'php5', 'php6', 'php7', 'phps', 'cgi', 'pl', 'asp',
'aspx', 'shtml', 'shtm', 'htaccess', 'htpasswd', 'ini', 'log', 'sh', 'js', 'html',
'htm', 'css', 'sql', 'spl', 'scgi', 'fcgi', 'exe'
);
// Директория куда будут загружаться файлы.
$path = __DIR__ . '/uploads/';
$data = array();
if (!isset($_FILES[$input_name])) {
$error = 'Файлы не загружены.';
} else {
// Преобразуем массив $_FILES в удобный вид для перебора в foreach.
$files = array();
$diff = count($_FILES[$input_name]) - count($_FILES[$input_name], COUNT_RECURSIVE);
if ($diff == 0) {
$files = array($_FILES[$input_name]);
} else {
foreach($_FILES[$input_name] as $k => $l) {
foreach($l as $i => $v) {
$files[$i][$k] = $v;
}
}
}
foreach ($files as $file) {
$error = $success = '';
// Проверим на ошибки загрузки.
if (!empty($file['error']) || empty($file['tmp_name'])) {
$error = 'Не удалось загрузить файл.';
} elseif ($file['tmp_name'] == 'none' || !is_uploaded_file($file['tmp_name'])) {
$error = 'Не удалось загрузить файл.';
} else {
// Оставляем в имени файла только буквы, цифры и некоторые символы.
$pattern = "[^a-zа-яё0-9,~!@#%^-_\$\?\(\)\{\}\[\]\.]";
$name = mb_eregi_replace($pattern, '-', $file['name']);
$name = mb_ereg_replace('[-]+', '-', $name);
$parts = pathinfo($name);
if (empty($name) || empty($parts['extension'])) {
$error = 'Недопустимый тип файла';
} elseif (!empty($allow) && !in_array(strtolower($parts['extension']), $allow)) {
$error = 'Недопустимый тип файла';
} elseif (!empty($deny) && in_array(strtolower($parts['extension']), $deny)) {
$error = 'Недопустимый тип файла';
} else {
// Перемещаем файл в директорию.
if (move_uploaded_file($file['tmp_name'], $path . $name)) {
// Далее можно сохранить название файла в БД и т.п.
$success = 'Файл «' . $name . '» успешно загружен.';
} else {
$error = 'Не удалось загрузить файл.';
}
}
}
if (!empty($success)) {
$data[] = '<p style="color: green">' . $success . '</p>';
}
if (!empty($error)) {
$data[] = '<p style="color: red">' . $error . '</p>';
}
}
}
// Вывод сообщений о результате загрузки.
header('Content-Type: application/json');
echo json_encode($data, JSON_UNESCAPED_UNICODE);
exit();
Пример работы:
Не забудьте в директории куда помещаются загруженные файлы запретить выполнение PHP-скриптов.