Чтобы вызвать меню загрузки файла при клике на абсолютно любой элемент html документа, достаточно создать невидимый(почти невидимый) input и при событии его изменения создается объект FormData в который помещаем файлы отправляя по ajax при помощи jquery. Полностью display:none; для input ставить нельзя, это обходится так:
$(document).on('click', '[data-file]', function () { $('#file').remove(); let input = document.createElement('input'); input.setAttribute('type', 'file'); input.setAttribute('id', 'file'); input.setAttribute('accept', '.png, .jpg, .jpeg, .gif'); input.style.cssText = 'width:0.1px;height:0.1px;opacity:0;overflow:hidden;position:absolute;z-index:-1;'; document.body.appendChild(input); input.click(); }); $(document).on('change', '#file', function () { let formData = new FormData(); formData.append('file', $("#file")[0].files[0]); $.ajax({ type: "POST", url: '/api/upload', cache: false, contentType: false, processData: false, data: formData }) .always(function () { $('#file').remove(); }); });
При клике на элементы с атрибутом data-file будет вызвано системное меню загрузки файла. Это пример отправки файла по ajax без дополнительных прибамбасов. На бекенд прилетает массив $_FILES[‘file’] и с ним далее работаем, не забывая соблюдать ТБ файловой загрузки на сервер.
Пример с простеньким обработчиком, загружаем пару файлов logo.png и icon.png по очереди:
<?php
if (!empty($_FILES['file'])) {
// Допустимые расширения файлов
$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif'];
$imageFileType = strtolower(pathinfo(basename($_FILES["file"]["name"]), PATHINFO_EXTENSION));
// Проверить, является ли файл изображением
$check = getimagesize($_FILES["file"]["tmp_name"]);
if ($check === false) {
http_response_code(400);
die("File is not an image.");
}
// Проверить расширение файла
if (!in_array($imageFileType, $allowed_extensions)) {
http_response_code(400);
die("Sorry, only JPG, JPEG, PNG & GIF files are allowed.");
}
$target_file = !file_exists(__DIR__ . '/../../logo/logo.png') ? __DIR__ . '/../../logo/logo.png' : __DIR__ . '/../../logo/icon.png';
file_exists(__DIR__ . '/../../logo') or mkdir(__DIR__ . '/../../logo', 0755) or die("Path not created");
// Попытаться переместить загруженный файл
if (!move_uploaded_file($_FILES["file"]["tmp_name"], $target_file)) {
http_response_code(400);
die("Sorry, there was an error uploading your file.");
}
exit;
}
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" crossorigin="anonymous">
<title>Загрузить</title>
<style>
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 offset-md-3">
<div class="card">
<div class="card-body">
<button id="button" type="button" class="btn btn-primary btn-block">Загрузить <?= !file_exists(__DIR__ . '/../../logo/logo.png') ? 'logo.png' : 'icon.png' ?></button>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script>
$(document).on('click', '#button', function() {
$('#file').remove();
let input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('id', 'file');
input.setAttribute('accept', '.png, .jpg, .jpeg, .gif');
input.style.cssText = 'width:0.1px;height:0.1px;opacity:0;overflow:hidden;position:absolute;z-index:-1;';
document.body.appendChild(input);
input.click();
});
$(document).on('change', '#file', function() {
let formData = new FormData();
formData.append('file', $("#file")[0].files[0]);
$.ajax({
type: "POST",
url: '/',
cache: false,
contentType: false,
processData: false,
data: formData
})
.fail(function(data) {
alert(`${data.statusText}: ${data.responseText}`);
})
.done(function() {
location.reload();
})
.always(function() {
$('#file').remove();
});
});
</script>
</body>
</html>