Загрузка файла jQuery с использованием jQuery ajax-метода (без плагинов)
В данный момент я хочу реализовать загрузку изображений без использования каких-либо подключаемых модулей.
Моя форма загрузки выглядит следующим образом
<form action="/Member/UploadPicture" enctype="multipart/form-data" id="uploadform" method="post">
<span>
<div class="upload" id="imgUpl">
<h3>Upload profile picture</h3>
<div class="clear5"></div>
<input type="file" name="file" id="file" />
<button class="btn-bl" id="upComplete"><span>Upload</span></button>
</div>
</span>
</form>
И мой код jQuery:
$('#upComplete').click(function () {
$('#up').hide();
$('#upRes').show();
var form = $("#uploadform");
$.ajax({
type: "POST",
url: "/Member/UploadPicture",
data: form.serialize(),
success: function (data) {
alert(data);
}
});
$.fancybox.close();
return false;
});
Если я открою firebug, я вижу, что метод ajax() делает сообщение простой формы (не многочастный) и содержимое POST пуст
Можно ли загружать файлы с использованием метода jQuery ajax(), или я должен делать это любым другим способом?
Большое спасибо
Ответы
Ответ 1
jQuery ajax не поддерживает загрузку файлов, и реализация этого вручную может быть громоздкой. Я бы предложил вам посмотреть плагин jQuery form.
Конечно, вы всегда можете проверить исходный код плагина, чтобы узнать, как он реализован, если вы не хотите его включать (он использует скрытый iFrame, поскольку файлы не могут быть загружены с помощью AJAX), но зачем это делать, если вы можете использовать его непосредственно: -)
Вот пример, как выглядит ваш код:
$(function() {
$('#uploadform').ajaxForm();
});
также сделайте кнопку загрузки кнопкой отправки:
<button class="btn-bl" id="upComplete" type="submit">
<span>Upload</span>
</button>
Ответ 2
AJAX
или более подходящий XMLHttpRequest
пока не поддерживает загрузку файлов. Возможны обходные пути, например, загрузка через <iframe>
, но довольно громоздкая. Ваше время будет лучше потрачено на создание приложений, а не на повторное использование этих решений.
Но если вы знаете, как это работает внутри, то не стесняйтесь проверить исходный код некоторых плагинов, предлагающих эту функцию. Очень простое объяснение можно найти по этой ссылке - http://www.openjs.com/articles/ajax/ajax_file_upload/
В принципе, вы меняете форму target
, чтобы отправить внутри <iframe>
, тем самым избегая обновления страницы и имитируя AJAX, что на самом деле не так, но кто заботится - конечный пользователь не может сказать.
Минимальный пример загрузки на основе iframe может выглядеть следующим образом:
$("#upComplete").click(function() {
// create a dynamic iframe, or use existing one
var iframe = $("<iframe id='f' name='f' src=''>");
// attach a load event to handle response/ know about completion
iframe.load(function() { alert('complete'); });
iframe.appendTo('body');
// change form target to the iframe (this is what simulates ajax)
$('#uploadForm').attr('target', 'f');
$('#uploadForm').submit();
});
Обратите внимание, что это не делает никакой обработки ответа, а просто отправляет изображение на сервер. Чтобы обработать ответ, обратный вызов должен быть записан для события iframe load
.
Ответ 3
На самом деле существует способ загрузки файлов с помощью ajax (xmlhttp) с помощью Firefox > 3 и Chrome, а также возможность загрузки нескольких файлов без использования форм и iframes. На самом деле я делаю плагин jQuery для этого, и вскоре я опубликую его. Вот простой пример:
var file=$('<input type=file />').get(0).files[0];
function asyncupload(file)
{
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function()
{
if (xhr.readyState == 4)
{
if ((xhr.status >= 200 && xhr.status <= 200) || xhr.status == 304)
{
//alert(xhr.responseText);
}
}
};
xhr.upload.onload=function(e)
{
$('div#axprogress').progressbar("option", "value", 100);;
};
xhr.upload.onprogress=function(e)
{
if (e.lengthComputable)
{
var perc = Math.round((e.loaded * 100) / e.total);
$('div#axprogress').progressbar("option", "value", perc);
}
};
xhr.open("POST", "upload.php?filename="+file.name,true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Name", encodeURIComponent(file.name));
xhr.send(file);
return xhr;
}
Для получения файлов на стороне сервера, например php, необходимо сделать это для upload.php:
$input = fopen("php://input", "r");
$temp = tmpfile();
$realSize = stream_copy_to_stream($input, $temp);
fclose($input);
if ($realSize != $this->getSize())
{
return false;
}
$target = fopen($_GET['filename'], "w");
fseek($temp, 0, SEEK_SET);
stream_copy_to_stream($temp, $target);
fclose($target);
Это простой пример идеи, а не полная работа script. Надеюсь это поможет. Для получения дополнительной информации см. https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest
Ответ 4
В то время как вы можете создать тело запроса multipart/form-data
самостоятельно, чтобы включить поле для загрузки файлов, оно не поможет вам, потому что вы не можете читать файлы на стороне клиента из поля загрузки файла.
(За исключением использования FileList, но в настоящее время только Firefox поддерживает это.)
Ответ 5
<input type="file" id="picfile" name="picf" />
<input type="text" id="txtName" style="width: 144px;" />
<input type="button" value=" ADD " id="btncatsave" style="width: 75px" />
$("#btncatsave").click(function () {
var Name = $("#txtName").val();
var formData = new FormData();
var totalFiles = document.getElementById("picfile").files.length;
var file = document.getElementById("picfile").files[0];
formData.append("FileUpload", file);
formData.append("Name", Name);
$.ajax({
type: "POST",
url: '/Category_Subcategory/Save_Category',
data: formData,
dataType: 'json',
contentType: false,
processData: false,
success: function (msg) {
alert(msg);
},
error: function (error) {
alert("errror");
}
});
});
[HttpPost]
public ActionResult Save_Category()
{
string Name=Request.Form[1];
if (Request.Files.Count > 0)
{
HttpPostedFileBase file = Request.Files[0];
}
}