Я хочу загрузить файл асинхронно с помощью jQuery.
$(document).ready(function () {
$("#uploadbutton").click(function () {
var filename = $("#file").val();
$.ajax({
type: "POST",
url: "addFile.do",
enctype: 'multipart/form-data',
data: {
file: filename
},
success: function () {
alert("Data Uploaded: ");
}
});
});
});<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<span>File</span>
<input type = "file" id = "file" name = "file" size = "10"/>
<input id = "uploadbutton" type = "button" value = "Upload"/>Вместо загружаемого файла я получаю только имя файла. Что я могу сделать, чтобы решить эту проблему?
Вот хороший вариант: http://blueimp.github.io/jQuery-File-Upload/ - Загрузка HTML5 ajax - Изящный возврат к iframe для неподдерживаемых браузеров - Асинхронная загрузка нескольких файлов Мы использовали его, и он отлично работает. (Документация здесь)
Также проверьте это: stackoverflow.com/questions/6974684/…, здесь объясняется, как этого добиться с помощью jQuery.
@ Джимми Как бы он вместо этого получил файл, который находится на входе?
Я наткнулся на несколько действительно мощных библиотек для загрузки файлов на основе jQuery. Проверьте это: 1. Plupload - документы: plupload.com/docs 2. Загрузка файла jQuery - документы: github.com/blueimp/jQuery-File-Upload 3. FineUploader - документы: docs.fineuploader.com
Существуют различные готовые плагины для загрузки файлов для jQuery. Выполнение такого рода хаков для загрузки не доставляет удовольствия, поэтому людям нравится использовать готовые решения. Вот несколько: - Загрузчик файлов JQuery - Плагин для загрузки нескольких файлов - Загрузка нескольких мини-файлов - Загрузка файла jQuery Вы можете искать больше проектов в NPM (используя «jquery-plugin» в качестве ключевого слова) или на Github.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Примечание. Этот ответ устарел, теперь можно загружать файлы с помощью XHR.
Вы не можете загружать файлы с помощью XMLHttpRequest (Ajax). Эффект можно смоделировать с помощью iframe или Flash. Отличный Плагин jQuery Form, который отправляет ваши файлы через iframe, чтобы получить эффект.
Да, вы можете выполнить POST в iframe и сохранить там файл. Однако у меня очень ограниченный опыт работы с этим, поэтому я не могу это комментировать.
Небольшое замечание: в последних версиях chrome и firefox это возможно, stackoverflow.com/questions/4856917/…
Не поддерживается в IE9 и ниже
При использовании «нового» HTML5 file API важно понимать, что это не поддерживался до IE 10. Если конкретный рынок, на который вы нацелены, имеет склонность к более старым версиям Windows выше среднего, у вас может не быть к нему доступа.
По состоянию на 2017 год около 5% браузеров относятся к IE 6, 7, 8 или 9. Если вы направитесь в большую корпорацию (например, это инструмент B2B или что-то, что вы предлагаете для обучения), это число может резко возрасти. . В 2016 году я имел дело с компанией, использующей IE8 на более чем 60% своих компьютеров.
На момент этой правки 2019 год, спустя почти 11 лет после моего первоначального ответа. IE9 и ниже имеют глобально около отметки 1%, но все еще есть кластеры с более высоким использованием.
Важным выводом из этого - какой бы ни была функция - является проверьте, какой браузер используют пользователи ваш. Если вы этого не сделаете, вы получите быстрый и болезненный урок о том, почему «работает на меня» недостаточно для доставки клиенту. могу ли я использовать - полезный инструмент, но обратите внимание, откуда они берут свои демографические данные. Они могут не совпадать с вашими. Это никогда не бывает более справедливым, чем в корпоративной среде.
Мой ответ от 2008 года следует.
Однако есть жизнеспособные методы загрузки файлов, отличные от JS. Вы можете создать iframe на странице (который вы скрываете с помощью CSS), а затем настроить таргетинг своей формы для публикации в этом iframe. Главную страницу перемещать не нужно.
Это «настоящий» пост, поэтому он не полностью интерактивен. Если вам нужен статус, вам нужно что-то на стороне сервера, чтобы его обработать. Это сильно зависит от вашего сервера. ASP.NET имеет более приятные механизмы. Простой PHP не работает, но вы можете использовать модификации Perl или Apache, чтобы обойти это.
Если вам нужно несколько загрузок файлов, лучше всего загружать каждый файл по одному (чтобы преодолеть максимальные ограничения загрузки файлов). Опубликуйте первую форму в iframe, следите за ее ходом, используя приведенные выше инструкции, а когда она будет завершена, опубликуйте вторую форму в iframe и т. д.
Или используйте решение Java / Flash. Они намного более гибки в том, что они могут делать со своими сообщениями ...
Для записи теперь можно выполнять загрузку файлов в чистом формате AJAX, если браузер поддерживает File API - developer.mozilla.org/en/using_files_from_web_applications
это довольно старый ответ, но он немного вводит в заблуждение. IE изначально поддерживал XHR еще в IE7 и поддерживал его через ActiveX еще в IE5. w3schools.com/ajax/ajax_xmlhttprequest_create.asp. Практический способ сделать это определенно заключался в нацеливании на компоненты вспышки (ударной волны) или развертывании элемента управления Flash / ActiveX (Silverlight). Если вы можете создать запрос и обработать ответ через javascript, это ajax ... хотя, как уже говорилось, ajax является синонимом xhr, но сам по себе не описывает механизм / компоненты подчеркивания, которые доставляют / обменивают полезную нагрузку.
@BrettCaswell Я не говорил, что AJAX / XHR невозможно, просто невозможно было опубликовать файл с ними в старых, но вечно существующих версиях IE. Это было и остается полностью верным.
Решение, которое я нашел, заключалось в том, чтобы <form> нацелился на скрытый iFrame. Затем iFrame может запустить JS, чтобы показать пользователю, что он завершен (при загрузке страницы).
Меня интересует этот ответ, есть ли у вас демонстрация, на которую можно ссылаться?
Я рекомендую для этого использовать плагин Fine Uploader. Ваш код JavaScript будет:
$(document).ready(function() {
$("#uploadbutton").jsupload({
action: "addFile.do",
onComplete: function(response){
alert( "server response: " + response);
}
});
});
Он использует JSON - поэтому для старой версии PHP его невозможно будет использовать.
Новый URL для версии 2 теперь valums-file-uploader.github.com/file-uploader
«Этот плагин имеет открытый исходный код под GNU GPL 2 или новее и GNU LGPL 2 или новее». Итак, пока вы не распространяете копию или измененную версию, вам не нужно открывать свой проект.
@Kerry У вас есть ссылка на лицензию MIT? Последняя версия (версия 4) выглядит как GPL3 Только, без LGPL: github.com/Widen/fine-uploader#license Версия 2 упоминает LGPL: valums-file-uploader.github.io/file-uploader
@DarrenCook Да, я заметил это в начале этого года. У меня есть загруженная копия старого кода, не такая красивая, но у нее все еще есть старая лицензия, но не в Интернете.
@BryanLarsen Вам не нужно выпускать код, если это веб-сайт (или решение SaaS), поскольку вы не распространяете «двоичный код», вам не нужно распространять код. Некоторые ресурсы: stackoverflow.com/questions/3701011/…
Начиная с Fine Uploader 5.9.0, библиотека теперь является 100% бесплатным программным обеспечением с открытым исходным кодом и лицензируется MIT.
Я написал это в среде Rails. Это всего лишь около пяти строк JavaScript, если вы используете облегченный плагин jQuery-form.
Проблема заключается в том, чтобы заставить AJAX-загрузку работать, поскольку стандартный remote_form_for не поддерживает отправку многочастных форм. Он не будет отправлять данные файла, которые Rails ищет обратно с запросом AJAX.
Вот где в игру вступает плагин jQuery-form.
Вот код Rails для этого:
<% remote_form_for(:image_form,
:url => { :controller => "blogs", :action => :create_asset },
:html => { :method => :post,
:id => 'uploadForm', :multipart => true })
do |f| %>
Upload a file: <%= f.file_field :uploaded_data %>
<% end %>
Вот связанный код JavaScript:
$('#uploadForm input').change(function(){
$(this).parent().ajaxSubmit({
beforeSubmit: function(a,f,o) {
o.dataType = 'json';
},
complete: function(XMLHttpRequest, textStatus) {
// XMLHttpRequest.responseText will contain the URL of the uploaded image.
// Put it in an image element you create, or do with it what you will.
// For example, if you have an image elemtn with id "my_image", then
// $('#my_image').attr('src', XMLHttpRequest.responseText);
// Will set that image tag to display the uploaded image.
},
});
});
А вот и довольно ванильное действие контроллера Rails:
@image = Image.new(params[:image_form])
@image.save
render :text => @image.public_filename
Я использую это в течение последних нескольких недель с Bloggity, и это сработало как чемпион.
Этот Плагин jQuery для загрузки файла AJAX каким-то образом загружает файл и передает ответ на обратный вызов, больше ничего.
<input type = "file">- Используйте всего лишь -
$('#one-specific-file').ajaxfileupload({
'action': '/upload.php'
});
- или столько же -
$('input[type = "file"]').ajaxfileupload({
'action': '/upload.php',
'params': {
'extra': 'info'
},
'onComplete': function(response) {
console.info('custom handler for file:');
alert(JSON.stringify(response));
},
'onStart': function() {
if (weWantedTo) return false; // cancels upload
},
'onCancel': function() {
console.info('no file selected');
}
});
С HTML5 вы можете загружать файлы с помощью Ajax и jQuery. Мало того, вы можете выполнять проверки файлов (имя, размер и MIME-тип) или обрабатывать событие прогресса с помощью тега прогресса HTML5 (или div). Недавно мне пришлось создать загрузчик файлов, но я не хотел использовать ни Вспышка, ни Iframes, ни плагины, и после некоторых исследований я нашел решение.
HTML:
<form enctype = "multipart/form-data">
<input name = "file" type = "file" />
<input type = "button" value = "Upload" />
</form>
<progress></progress>
Во-первых, вы можете выполнить некоторую проверку, если хотите. Например, в событии .on('change') файла:
$(':file').on('change', function () {
var file = this.files[0];
if (file.size > 1024) {
alert('max upload size is 1k');
}
// Also see .name, .type
});
Теперь $.ajax() отправляется нажатием кнопки:
$(':button').on('click', function () {
$.ajax({
// Your server script to process the upload
url: 'upload.php',
type: 'POST',
// Form data
data: new FormData($('form')[0]),
// Tell jQuery not to process data or worry about content-type
// You *must* include these options!
cache: false,
contentType: false,
processData: false,
// Custom XMLHttpRequest
xhr: function () {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
// For handling the progress of the upload
myXhr.upload.addEventListener('progress', function (e) {
if (e.lengthComputable) {
$('progress').attr({
value: e.loaded,
max: e.total,
});
}
}, false);
}
return myXhr;
}
});
});
Как видите, с HTML5 (и некоторыми исследованиями) загрузка файлов не только становится возможной, но и очень простой. Попробуйте использовать Гугл Хром, поскольку некоторые из компонентов HTML5 примеров доступны не во всех браузерах.
@ Silver89, если вы хотите вернуть данные из серверного сценария, который вы установили в настройке URL-адреса (в данном случае 'upload.php'), ответом будет то, что вы напечатаете или отобразите в этом сценарии. Затем вы можете делать с данными все, что захотите. Проверьте ajaxComplete и аналогичные функции в jQuery Docs
У меня работает файловая часть ... но можете ли вы включить в нее текстовые поля? Это не похоже на var formData = new FormData($('form')[0]); или serialize()?
с "новыми FormData ($ ('form') [0]);" он должен работать, у вашего текстового поля есть имя? используйте print_r в $ _POST, чтобы убедиться, что данные есть, проверьте ответ на сетевом мониторе (хром), чтобы увидеть необработанный ответ.
Могу ли я использовать $ _FILES в файле upload.php?
Это должно работать в Internet Explorer, но только в версии 10. (caniuse.com/xhr2)
Привет, я ценю, что PHP - ваш предпочтительный язык ... но мне интересно, знаете ли вы, работает ли это также в ASP.NET MVC? Я разработчик .NET, и я попытался использовать ваш простой пример для загрузки некоторых файлов AJAX, но на стороне сервера я не получаю файл, который я отправил через AJAX. Я использую последнюю версию Chrome.
Все волшебство здесь делает FormData. Обязательно ознакомьтесь с этими документами - они охватывают все ваши вопросы о нескольких файлах и полях.
Я использовал приведенный ниже сценарий для загрузки изображений, которые, как оказалось, работают нормально.
<input id = "file" type = "file" name = "file"/>
<div id = "response"></div>
jQuery('document').ready(function(){
var input = document.getElementById("file");
var formdata = false;
if (window.FormData) {
formdata = new FormData();
}
input.addEventListener("change", function (evt) {
var i = 0, len = this.files.length, img, reader, file;
for ( ; i < len; i++ ) {
file = this.files[i];
if (!!file.type.match(/image.*/)) {
if ( window.FileReader ) {
reader = new FileReader();
reader.onloadend = function (e) {
//showUploadedItem(e.target.result, file.fileName);
};
reader.readAsDataURL(file);
}
if (formdata) {
formdata.append("image", file);
formdata.append("extra",'extra-data');
}
if (formdata) {
jQuery('div#response').html('<br /><img src = "ajax-loader.gif"/>');
jQuery.ajax({
url: "upload.php",
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (res) {
jQuery('div#response').html("Successfully uploaded");
}
});
}
}
else
{
alert('Not a vaild image!');
}
}
}, false);
});
Я использую ответ div, чтобы показать анимацию загрузки и ответ после завершения загрузки.
Лучше всего то, что вы можете отправлять дополнительные данные, такие как идентификаторы и т. д. С файлом, когда вы используете этот скрипт. Я упомянул extra-data как в сценарии.
На уровне PHP это будет работать как обычная загрузка файла. дополнительные данные могут быть получены как данные $_POST.
Здесь вы не используете плагин и прочее. Вы можете изменить код как хотите. Вы здесь не слепо кодируете. Это основная функциональность любой загрузки файла jQuery. Собственно Javascript.
-1 для использования jQuery, а не использования его механизма выбора и обработчиков событий. addEventListener не является кроссбраузерным.
Потому что было бы бессмысленно добавлять отдельный ответ, который был бы в основном основан на этом, с небольшими изменениями. Вместо этого этот ответ следует исправить.
@RainFromHeaven, пожалуйста, отредактируйте ответ? Я не знаю, как это сделать кроссбраузерно.
По-прежнему не работает в IE 9 и ниже. Многие пользователи до сих пор используют эти версии IE.
Может кто-нибудь объяснить, как это можно сделать для работы в asp.net? Я использую веб-метод? Если да, то как бы это выглядело?
Вы можете легко сделать это на ванильном JavaScript. Вот отрывок из моего текущего проекта:
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e) {
var percent = (e.position/ e.totalSize);
// Render a pretty progress bar
};
xhr.onreadystatechange = function(e) {
if (this.readyState === 4) {
// Handle file upload complete
}
};
xhr.open('POST', '/upload', true);
xhr.setRequestHeader('X-FileName',file.name); // Pass the filename along
xhr.send(file);
@Gary: Извини, я тоже должен был опубликовать это. Я просто использовал новую функцию перетаскивания в HTML5; вы можете найти пример здесь: html5demos.com/file-api#view-source - просто нажмите «просмотреть исходный код». По сути, внутри события ondrop вы можете сделать var file = e.dataTransfer.files[0]
Возможно, с тех пор вопрос был отредактирован, но некоторые люди в обсуждении давайте, которое я открыл, думают, что ванильный ответ JS не по теме, если OP запрашивает решение jQuery (при условии, что оно существует), и такие ответы относятся к отдельному вопросу.
@ Энди Я не согласен, и, кажется, еще 34 тоже. Если вы можете использовать jQuery, вы, безусловно, можете использовать JavaScript. В любом случае, это сайт сообщества - это не просто ОП, которому я пытаюсь здесь помочь. Каждый волен выбрать / использовать тот ответ, который ему больше нравится. Некоторые люди просто тяготеют к jQuery, потому что думают, что это будет намного проще / меньше строк кода, хотя на самом деле им вообще не нужны накладные расходы на дополнительную библиотеку.
Я не уверен, что загружать файл таким способом - хорошая идея. Обычно файлы загружаются с использованием multipart / form-data. И серверы ожидают, что они могут быть большими. Я имею в виду, что если вы загрузите файл таким образом, он, скорее всего, окажется в памяти, независимо от его размера. С multipart / form-data он может храниться во временном файле. Но идея заманчивая :)
@ x-yuri Это метод лучше для обработки на стороне сервера. Все тело / полезная нагрузка может быть передана напрямую в файл или обработана по мере поступления. В случае multipart / form-data они должны быть проанализированы, прежде чем сервер сможет решить, что с ними делать.
Хорошая точка зрения. В любом случае, для полноты, загрузка файла с использованием multipart / form-data - это не намного сложнее.
jQuery Загрузить - еще один хороший плагин, который я использовал раньше для загрузки файлов. Код JavaScript очень прост: код. Однако новая версия не работает в Internet Explorer.
$('#file_upload').uploadify({
'swf': '/public/js/uploadify.swf',
'uploader': '/Upload.ashx?formGuid=' + $('#formGuid').val(),
'cancelImg': '/public/images/uploadify-cancel.png',
'multi': true,
'onQueueComplete': function (queueData) {
// ...
},
'onUploadStart': function (file) {
// ...
}
});
Я много искал и пришел к другому решению для загрузки файлов без каких-либо плагинов и только с ajax. Решение выглядит так:
$(document).ready(function () {
$('#btn_Upload').live('click', AjaxFileUpload);
});
function AjaxFileUpload() {
var fileInput = document.getElementById("#Uploader");
var file = fileInput.files[0];
var fd = new FormData();
fd.append("files", file);
var xhr = new XMLHttpRequest();
xhr.open("POST", 'Uploader.ashx');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
alert('success');
}
else if (uploadResult == 'success')
alert('error');
};
xhr.send(fd);
}
Uploadify был мертв уже много лет. Больше не поддерживается и не поддерживается.
Другой вариант - Simple Ajax Uploader:
https://github.com/LPology/Simple-Ajax-Uploader
Пример использования:
var uploader = new ss.SimpleUpload({
button: $('#uploadBtn'), // upload button
url: '/uploadhandler', // URL of server-side upload handler
name: 'userfile', // parameter name of the uploaded file
onSubmit: function() {
this.setProgressBar( $('#progressBar') ); // designate elem as our progress bar
},
onComplete: function(file, response) {
// do whatever after upload is finished
}
});
На данный момент это кажется наиболее многообещающим. Вы пригласили меня на IE7+! Пробуем прямо сейчас. Спасибо
Вы можете использовать
$(function() {
$("#file_upload_1").uploadify({
height : 30,
swf : '/uploadify/uploadify.swf',
uploader : '/uploadify/uploadify.php',
width : 120
});
});
Чтобы загрузить файл асинхронно с помощью JQuery, выполните следующие действия:
шаг 1 В вашем проекте откройте диспетчер Nuget и добавьте пакет (jquery fileupload (вам нужно только написать его в поле поиска, он появится и установит его.)) URL: https://github.com/blueimp/jQuery-File-Upload
шаг 2 Добавьте ниже скрипты в файлы HTML, которые уже добавлены в проект, запустив указанный выше пакет:
jquery.ui.widget.js
jquery.iframe-transport.js
jquery.fileupload.js
шаг 3 Запись управления загрузкой файла в соответствии с приведенным ниже кодом:
<input id = "upload" name = "upload" type = "file" />
шаг 4 напишите js-метод как uploadFile, как показано ниже:
function uploadFile(element) {
$(element).fileupload({
dataType: 'json',
url: '../DocumentUpload/upload',
autoUpload: true,
add: function (e, data) {
// write code for implementing, while selecting a file.
// data represents the file data.
//below code triggers the action in mvc controller
data.formData =
{
files: data.files[0]
};
data.submit();
},
done: function (e, data) {
// after file uploaded
},
progress: function (e, data) {
// progress
},
fail: function (e, data) {
//fail operation
},
stop: function () {
code for cancel operation
}
});
};
шаг 5 В готовой загрузке файла элемента вызова функции для запуска процесса, как показано ниже:
$(document).ready(function()
{
uploadFile($('#upload'));
});
шаг 6 Запишите контроллер MVC и действие, как показано ниже:
public class DocumentUploadController : Controller
{
[System.Web.Mvc.HttpPost]
public JsonResult upload(ICollection<HttpPostedFileBase> files)
{
bool result = false;
if (files != null || files.Count > 0)
{
try
{
foreach (HttpPostedFileBase file in files)
{
if (file.ContentLength == 0)
throw new Exception("Zero length file!");
else
//code for saving a file
}
}
catch (Exception)
{
result = false;
}
}
return new JsonResult()
{
Data=result
};
}
}
Преобразуйте файл в формат base64 с помощью | HTML5 readAsDataURL () или какой-то кодировщик base64. Скрипка здесь
var reader = new FileReader();
reader.onload = function(readerEvt) {
var binaryString = readerEvt.target.result;
document.getElementById("base64textarea").value = btoa(binaryString);
};
reader.readAsBinaryString(file);
Затем получить:
window.open("data:application/octet-stream;base64," + base64);
Самый простой и надежный способ, которым я делал это в прошлом, - просто настроить таргетинг на скрытый тег iFrame в вашей форме - тогда он будет отправлен в iframe без перезагрузки страницы.
Это если вы не хотите использовать плагин, JavaScript или любые другие формы «магии», кроме HTML. Конечно, вы можете комбинировать это с JavaScript или с чем-то еще ...
<form target = "iframe" action = "" method = "post" enctype = "multipart/form-data">
<input name = "file" type = "file" />
<input type = "button" value = "Upload" />
</form>
<iframe name = "iframe" id = "iframe" style = "display:none" ></iframe>
Вы также можете прочитать содержимое iframe onLoad на предмет ошибок сервера или успешных ответов, а затем вывести его пользователю.
Chrome, iFrames и onLoad
-Примечание- вам нужно продолжать читать, только если вам интересно, как настроить блокировщик пользовательского интерфейса при загрузке / скачивании
В настоящее время Chrome не запускает событие onLoad для iframe, когда он используется для передачи файлов. Firefox, IE и Edge запускают событие onload для передачи файлов.
Единственное решение, которое я нашел для Chrome, - это использование cookie.
Для этого в основном при запуске загрузки / выгрузки:
Использование cookie для этого некрасиво, но работает.
Я сделал плагин jQuery для решения этой проблемы для Chrome при загрузке, вы можете найти здесь
https://github.com/ArtisticPhoenix/jQuery-Plugins/blob/master/iDownloader.js
Тот же основной принцип применим и к загрузке.
Чтобы использовать загрузчик (очевидно, включая JS)
$('body').iDownloader({
"onComplete" : function(){
$('#uiBlocker').css('display', 'none'); //hide ui blocker on complete
}
});
$('somebuttion').click( function(){
$('#uiBlocker').css('display', 'block'); //block the UI
$('body').iDownloader('download', 'htttp://example.com/location/of/download');
});
А на стороне сервера, непосредственно перед передачей данных файла, создайте cookie
setcookie('iDownloader', true, time() + 30, "/");
Плагин увидит файл cookie, а затем вызовет обратный вызов onComplete.
Я люблю это. Если бы только кто-то мог упомянуть о потенциальных проблемах с этим блестящим решением. Я действительно не понимаю, почему люди пишут и используют эти неуклюжие библиотеки и плагины, когда есть решение.
Что ж, я думаю, причина в том, чтобы показать некоторую информацию о ходе загрузки.
Вы можете просто загрузить с помощью jQuery .ajax().
HTML:
<form id = "upload-form">
<div>
<label for = "file">File:</label>
<input type = "file" id = "file" name = "file" />
<progress class = "progress" value = "0" max = "100"></progress>
</div>
<hr />
<input type = "submit" value = "Submit" />
</form>
CSS
.progress { display: none; }
Javascript:
$(document).ready(function(ev) {
$("#upload-form").on('submit', (function(ev) {
ev.preventDefault();
$.ajax({
xhr: function() {
var progress = $('.progress'),
xhr = $.ajaxSettings.xhr();
progress.show();
xhr.upload.onprogress = function(ev) {
if (ev.lengthComputable) {
var percentComplete = parseInt((ev.loaded / ev.total) * 100);
progress.val(percentComplete);
if (percentComplete === 100) {
progress.hide().val(0);
}
}
};
return xhr;
},
url: 'upload.php',
type: 'POST',
data: new FormData(this),
contentType: false,
cache: false,
processData: false,
success: function(data, status, xhr) {
// ...
},
error: function(xhr, status, error) {
// ...
}
});
}));
});
Подведение итогов для будущих читателей.
Вы можете загружать файлы с jQuery с помощью метода $.ajax(), если поддерживаются FormData и Файловый API (обе функции HTML5).
Вы также можете отправлять файлы без FormData, но в любом случае должен присутствовать File API для обработки файлов таким образом, чтобы их можно было отправлять с помощью XMLHttpRequest (Ajax).
$.ajax({
url: 'file/destination.html',
type: 'POST',
data: new FormData($('#formWithFiles')[0]), // The form with the file inputs.
processData: false,
contentType: false // Using FormData, no need to process data.
}).done(function(){
console.info("Success: Files sent!");
}).fail(function(){
console.info("An error occurred, the files couldn't be sent!");
});
Для быстрого примера чистого JavaScript (нет jQuery) см. «Отправка файлов с помощью объекта FormData».
Когда HTML5 не поддерживается (без Файловый API), единственным другим решением на чистом JavaScript (без Вспышка или любого другого плагина для браузера) является метод скрытый iframe, который позволяет имитировать асинхронный запрос без использования объекта XMLHttpRequest.
Он состоит из установки iframe в качестве цели формы с входными данными файла. Когда пользователь отправляет запрос, выполняется загрузка файлов, но ответ отображается внутри iframe вместо повторного рендеринга главной страницы. Скрытие iframe делает весь процесс прозрачным для пользователя и имитирует асинхронный запрос.
Если все сделано правильно, он должен работать практически в любом браузере, но у него есть некоторые предостережения относительно того, как получить ответ от iframe.
В этом случае вы можете предпочесть использовать плагин-оболочку, такой как Бифрёст, который использует техника iframe, но также предоставляет транспорт jQuery Ajax, позволяющий Отправить файлы только с методом $.ajax(), например:
$.ajax({
url: 'file/destination.html',
type: 'POST',
// Set the transport to use (iframe means to use Bifröst)
// and the expected data type (json in this case).
dataType: 'iframe json',
fileInputs: $('input[type = "file"]'), // The file inputs containing the files to send.
data: { msg: 'Some extra data you might need.'}
}).done(function(){
console.info("Success: Files sent!");
}).fail(function(){
console.info("An error occurred, the files couldn't be sent!");
});
Бифрёст - это всего лишь небольшая оболочка, которая добавляет поддержку отката к методу ajax jQuery, но многие из вышеупомянутых подключаемых модулей, таких как Плагин jQuery Form или Загрузка файла jQuery, включают весь стек от HTML5 до различных резервных вариантов и некоторые полезные функции для упрощения процесса. В зависимости от ваших потребностей и требований вы можете рассмотреть простую реализацию или любой из этих плагинов.
Одно замечание, основанное на документации: вы также должны отправить contentType: false. Когда я не отправил это с помощью chrome, тип содержимого формы был аннулирован jQuery.
Хороший ответ. Несколько предложений по улучшению: удалите части кода, не связанные с ответом, например обратные вызовы .done() и .fail(). Кроме того, пример без использования FormData и список «за» / «против» был бы потрясающим.
У меня такая ошибка: TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.
Найдите здесь Асинхронная обработка процесса загрузки файла: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
Образец по ссылке
<?php
if (isset($_FILES['myFile'])) {
// Example:
move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
exit;
}
?><!DOCTYPE html>
<html>
<head>
<title>dnd binary upload</title>
<meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8">
<script type = "text/javascript">
function sendFile(file) {
var uri = "/index.php";
var xhr = new XMLHttpRequest();
var fd = new FormData();
xhr.open("POST", uri, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
// Handle response.
alert(xhr.responseText); // handle response.
}
};
fd.append('myFile', file);
// Initiate a multipart/form-data upload
xhr.send(fd);
}
window.onload = function() {
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = dropzone.ondragenter = function(event) {
event.stopPropagation();
event.preventDefault();
}
dropzone.ondrop = function(event) {
event.stopPropagation();
event.preventDefault();
var filesArray = event.dataTransfer.files;
for (var i=0; i<filesArray.length; i++) {
sendFile(filesArray[i]);
}
}
}
</script>
</head>
<body>
<div>
<div id = "dropzone" style = "margin:30px; width:500px; height:300px; border:1px dotted grey;">Drag & drop your file here...</div>
</div>
</body>
</html>
var formData=new FormData();
formData.append("fieldname","value");
formData.append("image",$('[name = "filename"]')[0].files[0]);
$.ajax({
url:"page.php",
data:formData,
type: 'POST',
dataType:"JSON",
cache: false,
contentType: false,
processData: false,
success:function(data){ }
});
Вы можете использовать данные формы для публикации всех ваших значений, включая изображения.
Примечание. cache: false является избыточным в запросе POST, поскольку кеширует POSTникогда.
@Vivek Aasaithambi, у меня такая ошибка: TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.
Это мое решение.
<form enctype = "multipart/form-data">
<div class = "form-group">
<label class = "control-label col-md-2" for = "apta_Description">Description</label>
<div class = "col-md-10">
<input class = "form-control text-box single-line" id = "apta_Description" name = "apta_Description" type = "text" value = "">
</div>
</div>
<input name = "file" type = "file" />
<input type = "button" value = "Upload" />
</form>
и js
<script>
$(':button').click(function () {
var formData = new FormData($('form')[0]);
$.ajax({
url: '@Url.Action("Save", "Home")',
type: 'POST',
success: completeHandler,
data: formData,
cache: false,
contentType: false,
processData: false
});
});
function completeHandler() {
alert(":)");
}
</script>
Контроллер
[HttpPost]
public ActionResult Save(string apta_Description, HttpPostedFileBase file)
{
[...]
}
Похоже, вы подмешали в свой ответ некую основу. Вы должны, по крайней мере, указать, для какой структуры подходит ваш ответ. А еще лучше удалить все элементы фреймворка и представить только ответ на поставленный вопрос.
так есть на самом деле фреймворк mvc под названием "mvc"? и он использует синтаксис csharpish? это жестоко.
Вот еще одно решение, как загрузить файл (без плагина)
Использование простых Яваскрипты и AJAX (с индикатором выполнения)
HTML часть
<form id = "upload_form" enctype = "multipart/form-data" method = "post">
<input type = "file" name = "file1" id = "file1"><br>
<input type = "button" value = "Upload File" onclick = "uploadFile()">
<progress id = "progressBar" value = "0" max = "100" style = "width:300px;"></progress>
<h3 id = "status"></h3>
<p id = "loaded_n_total"></p>
</form>
Часть JS
function _(el){
return document.getElementById(el);
}
function uploadFile(){
var file = _("file1").files[0];
// alert(file.name+" | "+file.size+" | "+file.type);
var formdata = new FormData();
formdata.append("file1", file);
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "file_upload_parser.php");
ajax.send(formdata);
}
function progressHandler(event){
_("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
var percent = (event.loaded / event.total) * 100;
_("progressBar").value = Math.round(percent);
_("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
}
function completeHandler(event){
_("status").innerHTML = event.target.responseText;
_("progressBar").value = 0;
}
function errorHandler(event){
_("status").innerHTML = "Upload Failed";
}
function abortHandler(event){
_("status").innerHTML = "Upload Aborted";
}
Часть PHP
<?php
$fileName = $_FILES["file1"]["name"]; // The file name
$fileTmpLoc = $_FILES["file1"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["file1"]["type"]; // The type of file it is
$fileSize = $_FILES["file1"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["file1"]["error"]; // 0 for false... and 1 for true
if (!$fileTmpLoc) { // if file not chosen
echo "ERROR: Please browse for a file before clicking the upload button.";
exit();
}
if (move_uploaded_file($fileTmpLoc, "test_uploads/$fileName")){ // assuming the directory name 'test_uploads'
echo "$fileName upload is complete";
} else {
echo "move_uploaded_file function failed";
}
?>
Вы можете увидеть решенное решение с помощью рабочей демонстрации здесь, которая позволяет просматривать и отправлять файлы форм на сервер. В вашем случае вам необходимо использовать Аякс для облегчения загрузки файла на сервер:
<from action = "" id = "formContent" method = "post" enctype = "multipart/form-data">
<span>File</span>
<input type = "file" id = "file" name = "file" size = "10"/>
<input id = "uploadbutton" type = "button" value = "Upload"/>
</form>
Отправляемые данные представляют собой данные формы. В jQuery используйте функцию отправки формы вместо нажатия кнопки, чтобы отправить файл формы, как показано ниже.
$(document).ready(function () {
$("#formContent").submit(function(e){
e.preventDefault();
var formdata = new FormData(this);
$.ajax({
url: "ajax_upload_image.php",
type: "POST",
data: formdata,
mimeTypes:"multipart/form-data",
contentType: false,
cache: false,
processData: false,
success: function(){
alert("successfully submitted");
});
});
});
Пример: если вы используете jQuery, вы можете легко загрузить файл. Это небольшой и мощный плагин jQuery, http://jquery.malsup.com/form/.
var $bar = $('.ProgressBar');
$('.Form').ajaxForm({
dataType: 'json',
beforeSend: function(xhr) {
var percentVal = '0%';
$bar.width(percentVal);
},
uploadProgress: function(event, position, total, percentComplete) {
var percentVal = percentComplete + '%';
$bar.width(percentVal)
},
success: function(response) {
// Response
}
});
Я надеюсь это будет полезно
Это старый вопрос, но до сих пор нет правильного ответа, поэтому:
Вы пробовали jQuery-File-Upload?
Вот пример из приведенной выше ссылки, который может решить вашу проблему:
$('#fileupload').fileupload({
add: function (e, data) {
var that = this;
$.getJSON('/example/url', function (result) {
data.formData = result; // e.g. {id: 123}
$.blueimp.fileupload.prototype
.options.add.call(that, e, data);
});
}
});
Используя HTML5 и JavaScript, загрузка async довольно проста, я создаю логику загрузки вместе с вашим html, это не полностью работает, так как ему нужен api, но продемонстрируйте, как это работает, если у вас есть конечная точка /upload из корня вашего веб-сайта , этот код должен работать для вас:
const asyncFileUpload = () => {
const fileInput = document.getElementById("file");
const file = fileInput.files[0];
const uri = "/upload";
const xhr = new XMLHttpRequest();
xhr.upload.onprogress = e => {
const percentage = e.loaded / e.total;
console.info(percentage);
};
xhr.onreadystatechange = e => {
if (xhr.readyState === 4 && xhr.status === 200) {
console.info("file uploaded");
}
};
xhr.open("POST", uri, true);
xhr.setRequestHeader("X-FileName", file.name);
xhr.send(file);
}<form>
<span>File</span>
<input type = "file" id = "file" name = "file" size = "10" />
<input onclick = "asyncFileUpload()" id = "upload" type = "button" value = "Upload" />
</form>Также некоторая дополнительная информация о XMLHttpReques:
The XMLHttpRequest Object
All modern browsers support the XMLHttpRequest object. The XMLHttpRequest object can be used to exchange data with a web server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page.
Create an XMLHttpRequest Object
All modern browsers (Chrome, Firefox, IE7+, Edge, Safari, Opera) have a built-in XMLHttpRequest object.
Syntax for creating an XMLHttpRequest object:
variable = new XMLHttpRequest();
Access Across Domains
For security reasons, modern browsers do not allow access across domains.
This means that both the web page and the XML file it tries to load, must be located on the same server.
The examples on W3Schools all open XML files located on the W3Schools domain.
If you want to use the example above on one of your own web pages, the XML files you load must be located on your own server.
Для более подробной информации вы можете продолжить чтение здесь ...
Вы можете использовать новееПолучить API с помощью JavaScript. Нравится:
function uploadButtonCLicked(){
var input = document.querySelector('input[type = "file"]')
fetch('/url', {
method: 'POST',
body: input.files[0]
}).then(res => res.json()) // you can do something with response
.catch(error => console.error('Error:', error))
.then(response => console.info('Success:', response));
}
Преимущество: Fetch API - это изначально поддерживается во всех современных браузерах, поэтому вам не нужно ничего импортировать. Также обратите внимание, что fetch () возвращает Обещать, который затем обрабатывается асинхронно с использованием .then(..code to handle response..).
Современный подход без JQuery заключается в использовании объекта FileList, который вы получаете от <input type = "file">, когда пользователь выбирает файл (ы), а затем с помощью Принести размещает FileList, обернутый вокруг объекта FormData.
// The input DOM element // <input type = "file">
const inputElement = document.querySelector('input[type=file]');
// Listen for a file submit from user
inputElement.addEventListener('change', () => {
const data = new FormData();
data.append('file', inputElement.files[0]);
data.append('imageName', 'flower');
// You can then post it to your server.
// Fetch can accept an object of type FormData on its body
fetch('/uploadImage', {
method: 'POST',
body: data
});
});
По-видимому, не поддерживается в IE
Вы можете выполнять асинхронную загрузку нескольких файлов с помощью JavaScript или jQuery и без использования какого-либо плагина. Вы также можете показать в реальном времени прогресс загрузки файла в контроле выполнения. Я нашел 2 хороших ссылки -
Серверный язык - C#, но вы можете внести некоторые изменения, чтобы заставить его работать с другим языком, таким как PHP.
Загрузка файла ASP.NET Core MVC:
В окне View создать элемент управления загрузкой файла в html:
<form method = "post" asp-action = "Add" enctype = "multipart/form-data">
<input type = "file" multiple name = "mediaUpload" />
<button type = "submit">Submit</button>
</form>
Теперь создайте метод действия в вашем контроллере:
[HttpPost]
public async Task<IActionResult> Add(IFormFile[] mediaUpload)
{
//looping through all the files
foreach (IFormFile file in mediaUpload)
{
//saving the files
string path = Path.Combine(hostingEnvironment.WebRootPath, "some-folder-path");
using (var stream = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(stream);
}
}
}
Переменная hostingEnvironment имеет тип IHostingEnvironment, который может быть введен в контроллер с помощью внедрения зависимостей, например:
private IHostingEnvironment hostingEnvironment;
public MediaController(IHostingEnvironment environment)
{
hostingEnvironment = environment;
}
Для PHP ищите https://developer.hyvor.com/php/image-upload-ajax-php-mysql
HTML
<html>
<head>
<title>Image Upload with AJAX, PHP and MYSQL</title>
</head>
<body>
<form onsubmit = "submitForm(event);">
<input type = "file" name = "image" id = "image-selecter" accept = "image/*">
<input type = "submit" name = "submit" value = "Upload Image">
</form>
<div id = "uploading-text" style = "display:none;">Uploading...</div>
<img id = "preview">
</body>
</html>
JAVASCRIPT
var previewImage = document.getElementById("preview"),
uploadingText = document.getElementById("uploading-text");
function submitForm(event) {
// prevent default form submission
event.preventDefault();
uploadImage();
}
function uploadImage() {
var imageSelecter = document.getElementById("image-selecter"),
file = imageSelecter.files[0];
if (!file)
return alert("Please select a file");
// clear the previous image
previewImage.removeAttribute("src");
// show uploading text
uploadingText.style.display = "block";
// create form data and append the file
var formData = new FormData();
formData.append("image", file);
// do the ajax part
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
var json = JSON.parse(this.responseText);
if (!json || json.status !== true)
return uploadError(json.error);
showImage(json.url);
}
}
ajax.open("POST", "upload.php", true);
ajax.send(formData); // send the form data
}
PHP
<?php
$host = 'localhost';
$user = 'user';
$password = 'password';
$database = 'database';
$mysqli = new mysqli($host, $user, $password, $database);
try {
if (empty($_FILES['image'])) {
throw new Exception('Image file is missing');
}
$image = $_FILES['image'];
// check INI error
if ($image['error'] !== 0) {
if ($image['error'] === 1)
throw new Exception('Max upload size exceeded');
throw new Exception('Image uploading error: INI Error');
}
// check if the file exists
if (!file_exists($image['tmp_name']))
throw new Exception('Image file is missing in the server');
$maxFileSize = 2 * 10e6; // in bytes
if ($image['size'] > $maxFileSize)
throw new Exception('Max size limit exceeded');
// check if uploaded file is an image
$imageData = getimagesize($image['tmp_name']);
if (!$imageData)
throw new Exception('Invalid image');
$mimeType = $imageData['mime'];
// validate mime type
$allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif'];
if (!in_array($mimeType, $allowedMimeTypes))
throw new Exception('Only JPEG, PNG and GIFs are allowed');
// nice! it's a valid image
// get file extension (ex: jpg, png) not (.jpg)
$fileExtention = strtolower(pathinfo($image['name'] ,PATHINFO_EXTENSION));
// create random name for your image
$fileName = round(microtime(true)) . mt_rand() . '.' . $fileExtention; // anyfilename.jpg
// Create the path starting from DOCUMENT ROOT of your website
$path = '/examples/image-upload/images/' . $fileName;
// file path in the computer - where to save it
$destination = $_SERVER['DOCUMENT_ROOT'] . $path;
if (!move_uploaded_file($image['tmp_name'], $destination))
throw new Exception('Error in moving the uploaded file');
// create the url
$protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://';
$domain = $protocol . $_SERVER['SERVER_NAME'];
$url = $domain . $path;
$stmt = $mysqli -> prepare('INSERT INTO image_uploads (url) VALUES (?)');
if (
$stmt &&
$stmt -> bind_param('s', $url) &&
$stmt -> execute()
) {
exit(
json_encode(
array(
'status' => true,
'url' => $url
)
)
);
} else
throw new Exception('Error in saving into the database');
} catch (Exception $e) {
exit(json_encode(
array (
'status' => false,
'error' => $e -> getMessage()
)
));
}
Вы можете передать дополнительные параметры вместе с именем файла при выполнении асинхронной загрузки с помощью XMLHttpRequest (без зависимости от flash и iframe). Добавьте значение дополнительного параметра с помощью FormData и отправьте запрос на загрузку.
var formData = new FormData();
formData.append('parameter1', 'value1');
formData.append('parameter2', 'value2');
formData.append('file', $('input[type=file]')[0].files[0]);
$.ajax({
url: 'post back url',
data: formData,
// other attributes of AJAX
});
Кроме того, загрузка файла пользовательского интерфейса JavaScript в Syncfusion предоставляет решение для этого сценария, просто используя аргумент события. вы можете найти документацию здесь и дополнительную информацию об этом элементе управления здесь введите описание ссылки здесь
Вы также можете использовать что-то вроде https://uppy.io.
Он выполняет загрузку файлов без перехода со страницы и предлагает несколько бонусов, таких как перетаскивание, возобновление загрузки в случае сбоев браузера / нестабильных сетей и импорт, например, из Instagram. Это открытый исходный код и не полагается на jQuery / React / Angular / Vue, но может использоваться вместе с ним. Отказ от ответственности: как его создатель я пристрастен;)
Вы можете использовать следующий код.
async: false(true)
Вы можете уточнить свой ответ? Непонятно, где сделать это изменение.
Вы можете добавить его в функцию вызова ajax
Это недопустимый синтаксис и не отвечает на этот вопрос.
Пытаться
async function saveFile()
{
let formData = new FormData();
formData.append("file", file.files[0]);
await fetch('addFile.do', {method: "POST", body: formData});
alert("Data Uploaded: ");
}<span>File</span>
<input type = "file" id = "file" name = "file" size = "10"/>
<input type = "button" value = "Upload" onclick = "saveFile()"/>content-type='multipart/form-data' устанавливается браузером автоматически, имя файла также автоматически добавляется к параметру filename FormData (и может быть легко прочитано сервером). Вот более проработанный пример с обработкой ошибок и добавлением json
async function saveFile(inp)
{
let user = { name:'john', age:34 };
let formData = new FormData();
let photo = inp.files[0];
formData.append("photo", photo);
formData.append("user", JSON.stringify(user));
try {
let r = await fetch('/upload/image', {method: "POST", body: formData});
console.info('HTTP response code:',r.status);
alert('success');
} catch(e) {
console.info('Huston we have problem...:', e);
}
}<input type = "file" onchange = "saveFile(this)" >
<br><br>
Before selecting the file Open chrome console > network tab to see the request details.
<br><br>
<small>Because in this example we send request to https://stacksnippets.net/upload/image the response code will be 404 ofcourse...</small>Что делать, если использовать обещания, которые используют ajax, и проверять, действителен ли файл и хорошо ли он сохранен в вашем бэкэнде, чтобы вы могли использовать некоторую анимацию впереди, пока пользователь перемещается по вашей странице.
Вы даже можете сделать параллельную загрузку или укладку с рекурсивным подходом.
вы получаете только имя файла, потому что ваше имя файла var получает значение $ ('# file'), а не файл, который находится на входе