страницы - отложить загрузку javascript




Как я могу загружать файлы асинхронно? (20)

Я хотел бы загрузить файл асинхронно с помощью 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 для загрузки файлов.


2017 Обновление: все равно зависит от браузеров, использующих ваши демографические приложения.

Важное значение для понимания с помощью нового API-интерфейса HTML5 - это не поддерживается до IE 10 . Если конкретный рынок, на который вы нацеливаетесь, имеет более высокую, чем среднюю, предел для более старых версий Windows, у вас может не быть доступа к нему.

Начиная с 2017 года, около 5% браузеров являются одним из IE 6, 7, 8 или 9. Если вы направляетесь в большую корпорацию (например, это инструмент B2B или что-то, что вы доставляете для обучения), это число может ракета. Всего несколько месяцев назад - в 2016 году - я имел дело с компанией, использующей IE8 на более чем 60% своих машин.

Поэтому прежде чем что-либо сделать: проверьте, какой браузер использует ваш пользователь . Если вы этого не сделаете, вы научитесь быстрому и мучительному уроку в том, почему «работает для меня» недостаточно хорош для доставки клиенту.

Мой ответ от 2008 года.

Тем не менее, существуют жизнеспособные не-JS-методы загрузки файлов. Вы можете создать iframe на странице (которую вы скрываете с помощью CSS), а затем настроить таргетинг своей формы для публикации в iframe. На главной странице не нужно двигаться.

Это «реальный» пост, поэтому он не является полностью интерактивным. Если вам нужен статус, вам нужно что-то серверное для его обработки. Это зависит от вашего сервера. ASP.NET имеет более удобные механизмы. Ошибка PHP plain, но вы можете использовать модификации Perl или Apache, чтобы обойти это.

Если вам нужно несколько загрузок файлов, лучше делать каждый файл по одному (чтобы преодолеть максимальные пределы загрузки файлов). Отправляйте первую форму в iframe, отслеживайте ее прогресс, используя вышеприведенное и когда он закончил, разместите вторую форму в iframe и т. Д.

Или используйте решение Java / Flash. Они намного более гибки в том, что они могут делать со своими постами ...


jQuery Uploadify - еще один хороший плагин, который я раньше использовал для загрузки файлов. Код JavaScript прост, как показано ниже: code. Однако новая версия не работает в 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);
}

Вы легко можете сделать это в 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);

Вы можете просто загрузить 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) {
                // ...
            }
       });
    }));
});

Подведение итогов для будущих читателей.

Загрузка асинхронного файла

С HTML5

Вы можете загружать файлы с помощью jQuery, используя метод $.ajax() если FormData и API файлов поддерживаются (оба свойства HTML5).

Вы также можете отправлять файлы без FormData, но в любом случае 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.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

Для быстрого, чистого JavaScript ( без jQuery ) пример см. « Отправка файлов с использованием объекта FormData ».

Отступать

Когда HTML5 не поддерживается (нет Файлового API ), единственное другое чистое решение для JavaScript (без Flash или любого другого плагина браузера) - это скрытая техника iframe , которая позволяет эмулировать асинхронный запрос без использования объекта XMLHttpRequest .

Он состоит из установки iframe в качестве цели формы с входными файлами. Когда пользователь отправляет запрос, и файлы загружаются, но ответ отображается внутри iframe вместо повторной рендеринга главной страницы. Скрытие iframe делает весь процесс прозрачным для пользователя и эмулирует асинхронный запрос.

Если все сделано правильно, оно должно работать практически в любом браузере, но в нем есть некоторые предостережения о том, как получить ответ от iframe.

В этом случае вы можете предпочесть использовать плагин-оболочку, такой как Bifröst который использует технику 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.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

Плагины

Bifröst - это всего лишь небольшая оболочка, которая добавляет вспомогательную поддержку метода ajax jQuery, но многие из вышеупомянутых плагинов, таких как jQuery Form Plugin или jQuery File Upload, включают весь стек из HTML5 в различные резервные копии и некоторые полезные функции для облегчения процесса. В зависимости от ваших потребностей и требований вы можете рассмотреть голый вариант реализации или любой из этих плагинов.


Примечание. Этот ответ устарел, теперь можно загружать файлы с помощью XHR.

Вы не можете загружать файлы с помощью XMLHttpRequest (Ajax). Вы можете имитировать эффект, используя iframe или Flash. Отличный плагин формы jQuery, который отправляет ваши файлы через iframe, чтобы получить эффект.


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


С HTML5 вы можете сделать загрузку файлов с помощью Ajax и jQuery. Кроме того, вы можете выполнять проверки файлов (имя, размер и тип MIME) или обрабатывать событие прогресса с тегом прогресса HTML5 (или div). Недавно мне пришлось сделать загрузчик файлов, но я не хотел использовать Flash iframe или плагины, и после некоторых исследований я придумал решение.

HTML:

<form enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>
<progress></progress>

Во-первых, вы можете сделать некоторую проверку, если хотите. Например, в событии onChange файла:

$(':file').on('change', function() {
    var file = this.files[0];
    if (file.size > 1024) {
        alert('max upload size is 1k')
    }

    // Also see .name, .type
});

Теперь Ajax submit с нажатием кнопки:

$(':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 (и некоторым исследованием) загрузка файлов не только становится возможной, но и очень простой. Попробуйте в Google Chrome, поскольку некоторые из компонентов HTML5 в примерах недоступны в каждом браузере.


Существуют различные готовые плагины для загрузки файлов для jQuery.

Выполнение такого рода загрузочных хаков - не приятный опыт, поэтому людям нравится использовать готовые решения.

Вот несколько:

Вы можете искать больше проектов на NPM (используя «jquery-plugin» в качестве ключевого слова) или на Github.


Ты можешь использовать

$(function() {
    $("#file_upload_1").uploadify({
        height        : 30,
        swf           : '/uploadify/uploadify.swf',
        uploader      : '/uploadify/uploadify.php',
        width         : 120
    });
});

Demo


Я использовал приведенный ниже сценарий для загрузки изображений, которые, как оказалось, работают нормально.

HTML

<input id="file" type="file" name="file"/>
<div id="response"></div>

JavaScript

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 чтобы показать загрузку анимации и ответ после завершения загрузки.

Лучше всего вы можете отправлять дополнительные данные, такие как ids & etc, с файлом при использовании этого скрипта. Я упоминаю extra-data как в скрипте.

На уровне PHP это будет работать как обычная загрузка файлов. дополнительные данные могут быть получены как данные $_POST .

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



Чтобы загрузить файл асинхронно с помощью Jquery, выполните следующие действия:

Шаг 1 В вашем проекте откройте менеджер Nuget и добавьте пакет (jquery fileupload (только вам нужно записать его в поле поиска, он появится и установит его.)) URL: https://github.com/blueimp/jQuery-File- Загрузить

Шаг 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
                };


        }

    }

Это мое решение.

<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)
{
    return Json(":)");
}

Вы можете загружать асинхронные множественные файлы с помощью JavaScript или jQuery и без использования какого-либо плагина. Вы также можете показать ход загрузки файла в режиме реального времени в контроле прогресса. Я столкнулся с двумя хорошими ссылками -

  1. Функция загрузки файлов Mulitple на основе ASP.NET Web Forms с помощью панели прогресса
  2. ASP.NET MVC для загрузки нескольких файлов, сделанных в jQuery

Язык на стороне сервера - C #, но вы можете сделать некоторые изменения, чтобы заставить его работать с другим языком, таким как PHP.

Загрузка файла ASP.NET Core MVC:

В элементе управления представлением View create in 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);
        }
    }
}

hostEnvironment - переменная типа IHostingEnvironment, которая может быть введена контроллеру с использованием инъекции зависимостей, например:

private IHostingEnvironment hostingEnvironment;
public MediaController(IHostingEnvironment environment)
{
    hostingEnvironment = environment;
}

Вы можете использовать новый API Fetch с помощью 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.log('Success:', response));
}                               

Преимущество: API-интерфейс Fetch поддерживается всеми современными браузерами, поэтому вам не нужно ничего импортировать. Также обратите внимание, что fetch () возвращает Promise который затем обрабатывается .then(..code to handle response..)асинхронно.


Используя 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.log(percentage);
  };
  xhr.onreadystatechange = e => {
    if (xhr.readyState === 4 && xhr.status === 200) {
      console.log("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:

Объект XMLHttpRequest

Все современные браузеры поддерживают объект XMLHttpRequest. Объект XMLHttpRequest может использоваться для обмена данными с веб-сервером за кулисами. Это означает, что можно обновлять части веб-страницы без перезагрузки всей страницы.


Создать объект XMLHttpRequest

Все современные браузеры (Chrome, Firefox, IE7 +, Edge, Safari, Opera) имеют встроенный объект XMLHttpRequest.

Синтаксис для создания объекта XMLHttpRequest:

variable = new XMLHttpRequest ();


Доступ во всех доменах

По соображениям безопасности современные браузеры не разрешают доступ к доменам.

Это означает, что и веб-страница, и файл XML, который она пытается загрузить, должны быть расположены на одном сервере.

Примеры в W3Schools открывают все файлы XML, расположенные в домене W3Schools.

Если вы хотите использовать пример выше на одной из ваших собственных веб-страниц, загружаемые файлы XML должны размещаться на вашем собственном сервере.

Для более подробной информации вы можете продолжить чтение here ...


Посмотрите на обработку процесса загрузки для файла, асинхронно здесь: 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>

Пример. Если вы используете 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 заключается в использовании объекта 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
    })
});




upload