Как я могу загружать файлы асинхронно? - PullRequest
2765 голосов
/ 03 октября 2008

Я хотел бы загрузить файл асинхронно с jQuery. Это мой HTML:

<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

А вот мой 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: ");
            }
        });
    });
});

Вместо загружаемого файла я получаю только имя файла. Что я могу сделать, чтобы решить эту проблему?

Текущее решение

Я использую плагин jQuery Form для загрузки файлов.

Ответы [ 32 ]

32 голосов
/ 18 октября 2008

Решением, которое я нашел, было назначение цели <form> скрытого iFrame. Затем iFrame может запустить JS, чтобы показать пользователю, что он завершен (при загрузке страницы).

31 голосов
/ 14 августа 2009

Я написал это в среде Rails . Это всего лишь пять строк JavaScript, если вы используете облегченный плагин jQuery-формы.

Сложность заключается в том, чтобы загрузка AJAX работала как стандарт. remote_form_for не понимает отправку форм из нескольких частей. Он не собирается отправлять данные файла, которые Rails ищет обратно с помощью запроса AJAX.

Вот где плагин jQuery-формы вступает в игру.

Вот код 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, и он работал как чемпион.

30 голосов
/ 26 июня 2013

Простой Ajax Uploader - это еще один вариант:

https://github.com/LPology/Simple-Ajax-Uploader

  • Кросс-браузер - работает в IE7 +, Firefox, Chrome, Safari, Opera
  • Поддержка нескольких одновременных загрузок - даже в браузерах, отличных от HTML5
  • Нет флеш-памяти или внешнего CSS - только один 5-килобайтный файл Javascript
  • Необязательная встроенная поддержка полностью кросс-браузерных индикаторов прогресса (с использованием PHP-расширения APC)
  • Гибкость и широкие возможности настройки - используйте любой элемент в качестве кнопки загрузки, используйте собственные индикаторы прогресса
  • Никаких форм не требуется, просто укажите элемент, который будет использоваться в качестве кнопки загрузки
  • Лицензия MIT - бесплатно для использования в коммерческом проекте

Пример использования:

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
    }
});
22 голосов
/ 16 июня 2013

jQuery Uploadify - еще один хороший плагин, который я использовал для загрузки файлов. Код 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);
}
21 голосов
/ 30 марта 2016

Вот еще одно решение для загрузки файла ( без какого-либо плагина )

Использование простых JavaScript и 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 part

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 part

<?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";
}
?>

Вот пример приложения

15 голосов
/ 28 июля 2015
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){ }
});

Вы можете использовать данные формы для публикации всех ваших значений, включая изображения.

13 голосов
/ 23 июня 2014

Чтобы загрузить файл асинхронно с 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
                };


        }

    }
9 голосов
/ 23 июня 2014

Преобразование файла в 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);
8 голосов
/ 17 августа 2018

Современный подход без Jquery заключается в использовании объекта FileList , который вы получаете от <input type="file">, когда пользователь выбирает файл (ы) и затем использует Fetch для публикации FileList, обернутого вокруг объекта FormData .

// The input DOM element
const inputElement = document.querySelector('input');

// Listen for a file submit from user
inputElement.addEventListener('change', () => {
    const data = new FormData();
    data.append('file', inputElement.files[0]);
    data.append('imageName', 'flower');

    // Post to server
    fetch('/uploadImage', {
        method: 'POST',
        body: data
    });
});
8 голосов
/ 14 октября 2016

Пример: если вы используете 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
  }
});

Надеюсь, это будет полезно

...