Динамическое добавление файлов на вход
Я использую этот плагин: загрузчик jQuery HTML5 (см. Демонстрацию) внутри формы. Я хочу отправлять загруженные файлы методом POST, когда пользователь отправляет форму.
Может быть, я могу создать input[type="file"]
сделать его скрытым и динамически добавлять загруженные файлы с помощью плагина внутри ввода? Это возможно?
Итак, если я не могу этого сделать, как я могу загружать файлы на сервер с помощью этого плагина, только когда пользователь нажимает кнопку отправки? Я знаю, что плагин уже делает это с AJAX, но я хочу загружать их, только если пользователь нажимает кнопку.
Может быть, я должен создать переменную с именем, например, files
и когда пользователь нажимает на кнопку отправки, использовать AJAX для отправки файлов и остальных входных данных?
Что-то вроде этого:
jQuery( "#dropbox" ).html5Uploader({
onClientLoadStart: function( event, file ) {
files[] = file;
[...]
}
});
[...]
jQuery("#button").on("click", function() {
jQuery.ajax({
data: files
});
[...]
});
3 ответа
Вы не можете сделать это по соображениям безопасности. Просто представьте возможности. Я ввожу файл с помощью JavaScript в скрытом поле. Вы нажимаете отправить. Я получил ваш файл. Любой файл. Страшно, правда?
Вы не можете выбрать файл в загрузчике файлов из-за безопасности браузера.
Пользователь может сделать это только не сценарий.
Этот сценарий уже загружает файлы на сервер... вам нужен способ вернуть имя файла / идентификатор с сервера и прикрепить их к скрытой форме... чем когда кто-то отправляет форму, вы будете знать, какие файлы он загрузил.,
Вы можете сделать это, прослушивая событие onSuccess.
По соображениям безопасности нельзя динамически изменять значение поля ввода типа file. Если бы это было возможно, злонамеренный пользователь мог бы установить значение: "c:\malwarefile" и нанести вред вашей системе.
Похоже, ваш вопрос состоит из двух частей:
Как динамически добавлять файлы в форму с помощью JavaScript
1а. (Добавлю бонус - предварительный просмотр изображений)
Как выполнить загрузку файла Ajax
1 Динамическое добавление файлов в форму
Что вы хотите здесь сделать, создайте <input type="file">
поле и измените значение формы с помощью Javascript. Вы можете скрыть ввод с помощью CSSdisplay: none;
.
Насколько мне известно, это можно сделать только с помощью FileReader API и перетаскивания, а API ограничен.
Вы можете заменить и удалить все файлы из ввода, но не можете добавлять или удалять отдельные файлы.
Базовая загрузка файла перетаскиванием выглядит так:
const dropZone = document.getElementById('dropzone');
const fileInput = document.getElementById('file-input');
dropzone.addEventListener('dragover', event => {
// we must preventDefault() to let the drop event fire
event.preventDefault();
});
dropzone.addEventListener('drop', event => {
event.preventDefault();
// drag/drop files are in event.dataTransfer
let files = event.dataTransfer.files;
fileInput.files = files;
console.log(`added ${files.length} files`);
});
.upload {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px
}
.hidden {
opacity: 0.5;
}
<div id="dropzone" class="upload">Drop images here</div>
<input type="file" id="file-input" class="hidden" />
1a Предварительный просмотр файлов
Работа с Javascript открывает несколько забавных возможностей для взаимодействия с формами, таких как предварительный просмотр загруженных файлов. Возьмем, к примеру, программу загрузки изображений, которая может предварительно просмотреть несколько изображений, перетаскиваемых мышью.
const imageTypeFilter = /image.*/;
const dropZone = document.getElementById('dropzone');
const fileInput = document.getElementById('file-input');
const previewContainer = document.getElementById('preview-container');
function generateImagePreview(file) {
const fileReader = new FileReader();
fileReader.addEventListener('load', event => {
// generate an image preview
let image = document.createElement('img');
image.classList.add('preview-image');
srcAttr = document.createAttribute('src');
srcAttr.value = fileReader.result;
image.setAttributeNode(srcAttr);
previewContainer.append(image);
}, false);
// open and read the file
fileReader.readAsDataURL(file);
}
function processFiles(files) {
previewContainer.innerHTML = "";
([...files]).forEach((file, index) => {
if (!file.type.match(imageTypeFilter)) {
console.error("Incorrect file type:");
console.log(file);
} else {
generateImagePreview(file);
}
});
}
dropZone.addEventListener('dragover', event => {
// required to fire the drop event
event.preventDefault();
});
dropZone.addEventListener('drop', event => {
event.preventDefault();
const files = event.dataTransfer.files;
fileInput.files = files;
processFiles(files);
});
fileInput.addEventListener('change', event => {
processFiles(event.target.files);
});
.upload {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px
}
.preview-image {
max-width: 100px;
max-height: 100px;
}
.hidden {
opacity: 0.5;
}
<div id="dropzone" class="upload">
Drag images here
</div>
<input id="file-input" type="file" multiple accept="image/jpeg,image/png,image/gif" class="hidden" />
<div id="preview-container"></div>
2 Выполните загрузку AJAX, когда пользователь нажимает кнопку отправки.
В этом случае вы хотите переопределить событие отправки формы по умолчанию, которое, как мне кажется, будет выглядеть примерно так:
const submitUrl = 'https://httpbin.org/post';
const form = document.getElementById('ajax-form');
form.addEventListener('submit', event => {
// this line prevents the default submit
event.preventDefault();
// convert the form into POST data
const serializedFormData = new FormData(event.target);
// use your favorite AJAX library
axios.post(
submitUrl,
serializedFormData
).then(response => {
console.log("success!");
}).catch(error => {
console.log("falied");
console.log(error.response);
});
});
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<form id="ajax-form" method="post" enctype="multipart/form-data">
<input type="text" name="name"/>
<input name="file" type="file" />
<button type="submit">Submit</button>
</form>