Как я могу загружать файлы асинхронно с помощью jQuery?

avatar
Sergio del Amo
3 октября 2008 в 10:22
1413026
34
3042

Я хочу асинхронно загрузить файл с помощью 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"/>

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

Источник
Cheery
15 октября 2008 в 10:35
0

Существуют различные готовые плагины для загрузки файлов для jQuery. Выполнение такого рода хаков для загрузки не доставляет удовольствия, поэтому людям нравится использовать готовые решения. Вот некоторые из них: - JQuery File Uploader - Плагин для загрузки нескольких файлов - Мини-загрузка нескольких файлов - Вы можете выполнить поиск проекты на NPM (используя "jquery-plugin" в качестве ключевого слова) или на Github.

Jimmy
3 ноября 2009 в 16:01
77

вы получаете только имя файла, потому что ваше имя файла var получает значение $ ('# file'), а не файл, который находится на входе

Hristo
8 апреля 2011 в 16:43
0

Я наткнулся на несколько действительно мощных библиотек для загрузки файлов на основе jQuery. Проверьте это: 1. Plupload - документы: plupload.com/docs 2. Загрузка файла jQuery - docs: glue.com jQuery-File-Upload 3. FineUploader - документы: docs.fineuploader.com

Ashish Panery
12 апреля 2013 в 18:35
22

Вот хороший вариант: http://blueimp.github.io/jQuery-File-Upload/ - Загрузка HTML5 ajax - Изящный возврат к iframe для неподдерживаемых браузеров - Асинхронная загрузка нескольких файлов Мы использовали это и он отлично работает. (Документация здесь)

Federico J.
15 января 2014 в 12:09
3

Также проверьте это: coderhelper.com/questions/6974684/…, здесь объясняется, как этого добиться с помощью jQuery.

alex
5 декабря 2014 в 18:05
2

@ Джимми Как бы он вместо этого получил файл, который лежит на входе?

Ответы (34)

avatar
Diego Vinícius
28 февраля 2020 в 15:06
2

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

Вы даже можете сделать параллельную загрузку или стек с рекурсивным подходом

avatar
Kamil Kiełczewski
5 июля 2019 в 10:31
4

Попробуйте

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.log('HTTP response code:',r.status); 
       alert('success');
    } catch(e) {
       console.log('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>
avatar
Michael Wang
8 апреля 2019 в 12:14
2

Вы можете использовать следующий код.

async: false(true)
kabirbaidhya
14 сентября 2020 в 08:17
0

Вы можете уточнить свой ответ? Непонятно, где сделать это изменение.

Michael Wang
16 сентября 2020 в 00:09
0

Вы можете добавить его в функцию вызова ajax

Sebastian Simon
5 марта 2021 в 08:04
1

Это недопустимый синтаксис и не отвечает на этот вопрос.

avatar
kvz
21 декабря 2018 в 09:00
4

Вы также можете рассмотреть возможность использования чего-то вроде https://uppy.io.

Он выполняет загрузку файлов без перехода со страницы и предлагает несколько бонусов, таких как перетаскивание, возобновление загрузки в случае сбоев браузера / нестабильных сетей и импорт, например, из Instagram. Это открытый исходный код и не полагается на jQuery / React / Angular / Vue, но может использоваться вместе с ним. Отказ от ответственности: как его создатель я пристрастен;)

avatar
Karthik Ravichandran
14 ноября 2018 в 12:42
9

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

avatar
Supun Kavinda
5 октября 2018 в 10:45
4

Для 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()
        )
    ));
}
avatar
Joe Clinton
29 августа 2018 в 19:51
4

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

  1. Функция загрузки нескольких файлов на основе веб-форм ASP.NET с индикатором выполнения
  2. Загрузка нескольких файлов на основе ASP.NET MVC, выполненная в jQuery

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

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

В представлении создайте элемент управления загрузкой файла в 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;
}
avatar
Alister
17 августа 2018 в 11:47
18

Современный подход без JQuery заключается в использовании объекта FileList, который вы получаете обратно из <input type="file">, когда пользователь выбирает файл (ы), а затем использует <116756599> Fetch >, чтобы опубликовать список файлов, обернутый вокруг объекта 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
    });
});
avatar
BlackBeard
21 мая 2018 в 10:14
7

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

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

avatar
Alireza
12 марта 2018 в 12:32
6

Используя HTML5 и JavaScript , загружать асинхронно довольно просто, я создаю логику загрузки вместе с вашим 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:

переменная = новый XMLHttpRequest ();


Доступ через домены

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

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

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

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

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

avatar
lat94
21 февраля 2018 в 14:41
4

Это старый вопрос, но до сих пор нет правильного ответа, поэтому:

Вы пробовали 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);
        });
    } 
});
avatar
MEAbid
14 октября 2016 в 07:17
11

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

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

avatar
Daniel Nyamasyo
19 июля 2016 в 05:18
11

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

<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");

     });
   });
});

Подробнее

avatar
Siddhartha Chowdhury
30 марта 2016 в 16:48
26

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

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

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

Вот ПРИМЕР приложения

avatar
Erick Lanford Xenes
3 ноября 2015 в 20:47
9

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

<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)
{
    [...]
}
Zero3
19 декабря 2015 в 18:06
4

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

nonchip
6 января 2016 в 22:27
6

так есть на самом деле фреймворк mvc под названием "mvc"? и он использует синтаксис csharpish? это жестоко.

avatar
Vivek Aasaithambi
28 июля 2015 в 13:39
19
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){ }
});

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

avatar
Allende
8 июля 2015 в 17:59
8

Ищите Обработка процесса загрузки файла, асинхронно здесь: 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>
avatar
404
25 августа 2014 в 14:17
100

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

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

С HTML5

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

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

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

Откат

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

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

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

В этом случае вы можете предпочесть использовать плагин-оболочку, например Bifröst, который использует технику iframe , но также предоставляет jQuery Ajax Transport транспортный > отправить файлы с помощью метода $.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 - это всего лишь небольшая оболочка, которая добавляет резервную поддержку метода jQuery ajax, но многие из вышеупомянутых подключаемых модулей, таких как jQuery Form Plugin или <588500>Q> или <588500> jQuery Form Plugin, или <588500> включить весь стек от HTML5 к различным запасным вариантам и некоторые полезные функции, чтобы упростить процесс. В зависимости от ваших потребностей и требований, вы можете рассмотреть вариант реализации «голого» или любого из этих подключаемых модулей.

avatar
Zayn Ali
8 августа 2014 в 02:59
48

Вы можете просто загрузить с помощью 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) {
                // ...
            }
       });
    }));
});
avatar
ArtisticPhoenix
26 июня 2014 в 04:43
45

Самый простой и надежный способ, которым я делал это в прошлом, - просто настроить таргетинг на скрытый тег 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
  • [Сторона сервера] Делайте все, что вам нужно, с данными файла
  • [Сторона сервера] Установить cookie для интервала на стороне клиента
  • [Клиентская сторона] Interval видит файл cookie и использует его как событие onLoad. Например, вы можете запустить блокировщик пользовательского интерфейса, а затем onLoad (или при создании файла 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.

avatar
tnt-rox
23 июня 2014 в 18:50
9

Преобразуйте файл в 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);
avatar
ashish
23 июня 2014 в 08:18
15

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


        }

    }
avatar
Amit
12 мая 2014 в 10:10
10

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

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

Демо

avatar
user1091949
26 июня 2013 в 01:12
33

Другой вариант - простой Ajax Uploader:

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

  • Кроссбраузерность - работает в IE7 +, Firefox, Chrome, Safari, Opera
  • Поддерживает несколько одновременных загрузок - даже в браузерах, отличных от HTML5
  • Без Flash или внешнего CSS - только один файл Javascript размером 5 КБ
  • Дополнительная встроенная поддержка полностью кроссбраузерных индикаторов выполнения (с использованием расширения 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
    }
});
avatar
farnoush resa
16 июня 2013 в 09:49
26

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);
}
avatar
mpen
17 февраля 2013 в 09:34
53

Вы можете легко сделать это на обычном 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);
avatar
Techie
25 января 2013 в 11:03
63

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

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

Самое приятное, что вы можете отправлять дополнительные данные, такие как идентификаторы и т. Д., С файлом, когда вы используете этот скрипт. Я упомянул его extra-data как в сценарии.

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

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

avatar
olanod
6 января 2012 в 13:34
2574

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

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

olanod
13 мая 2012 в 19:49
1

@ Silver89, если вы хотите вернуть данные из серверного скрипта, который вы установили в настройках URL-адреса (в данном случае 'upload.php'), ответом будет то, что вы напечатаете или отобразите в этом скрипте. Затем вы можете делать с данными все, что захотите. Проверьте ajaxComplete и аналогичные функции в jQuery Docs

Dan
5 июня 2012 в 04:26
3

У меня работает файловая часть ... но можете ли вы включить в нее текстовые поля? Это не похоже на var formData = new FormData($('form')[0]); или serialize()?

olanod
5 июня 2012 в 10:57
0

с "новыми FormData ($ ('form') [0]);" он должен работать, у вашего текстового поля есть имя? используйте print_r в $ _POST, чтобы убедиться, что данные есть, проверьте ответ на сетевом мониторе (хром), чтобы увидеть необработанный ответ.

Alessandro Cosentino
2 ноября 2012 в 13:41
18

Могу ли я использовать $ _FILES в файле upload.php?

Tyler
2 января 2013 в 16:33
74

Это должно работать в Internet Explorer, но только в версии 10. (caniuse.com/xhr2)

Shumii
1 июня 2013 в 05:29
20

Привет, я ценю, что PHP - ваш предпочтительный язык ... но мне интересно, знаете ли вы, работает ли это также в ASP.NET MVC? Я разработчик .NET, и я попытался использовать ваш простой пример для загрузки некоторых файлов AJAX, но на стороне сервера я не получаю файл, который я отправил через AJAX. Я использую последнюю версию Chrome.

BorisOkunskiy
12 сентября 2013 в 13:26
27

Все волшебство здесь творит FormData. Обязательно ознакомьтесь с этими документами - они охватывают все ваши вопросы о нескольких файлах и полях.

avatar
Jordan Feldstein
29 июля 2011 в 00:34
86

Этот плагин jQuery для загрузки файла AJAX загружает файл где-то и передает ответ на обратный вызов, больше ничего.

  • Это не зависит от конкретного HTML, просто дайте ему <input type="file">
  • Это не требует, чтобы ваш сервер отвечал каким-либо определенным образом
  • Неважно, сколько файлов вы используете или где они находятся на странице

- Используйте всего -

$('#one-specific-file').ajaxfileupload({
  'action': '/upload.php'
});

- или столько же -

$('input[type="file"]').ajaxfileupload({
  'action': '/upload.php',
  'params': {
    'extra': 'info'
  },
  'onComplete': function(response) {
    console.log('custom handler for file:');
    alert(JSON.stringify(response));
  },
  'onStart': function() {
    if(weWantedTo) return false; // cancels upload
  },
  'onCancel': function() {
    console.log('no file selected');
  }
});
avatar
wbharding
13 августа 2009 в 22:44
33

Я написал это в среде 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, и он отлично работает.

avatar
pixxaar
21 ноября 2008 в 16:38
115

Я рекомендую использовать для этой цели плагин Fine Uploader. Ваш код JavaScript будет:

$(document).ready(function() {
  $("#uploadbutton").jsupload({
    action: "addFile.do",
    onComplete: function(response){
      alert( "server response: " + response);
    }
  });
});
Trantor Liu
23 июля 2012 в 12:02
36

«Этот плагин имеет открытый исходный код под GNU GPL 2 или новее и GNU LGPL 2 или новее». Итак, пока вы не распространяете копию или измененную версию, вам не нужно открывать свой проект.

Nick Albrecht
29 июля 2021 в 00:50
1

На случай, если кто-то попытается пойти по этому пути, FineUploader будет прекращен в 2018 году. github.com/FineUploader/fine-uploader/issues/2073

avatar
Darryl Hein
18 октября 2008 в 19:30
32

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

avatar
Oli
3 октября 2008 в 10:41
292

Обновление 2019: оно по-прежнему зависит от браузеров, ваших демографических целей.

Важно понимать, что «новый» HTML5 file API состоит в том, что он не поддерживался до IE 10. Если конкретный рынок, на который вы нацелены, имеет склонность к более старым версиям Windows выше среднего, у вас может не быть доступа к нему.

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

На момент этой правки 2019 год, почти 11 лет после моего первоначального ответа. IE9 и ниже имеют глобально около отметки 1%, но все еще есть кластеры с более высоким использованием.

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

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


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

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

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

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

meleyal
25 марта 2011 в 10:05
144

Для записи теперь можно выполнять загрузку файлов в чистом формате AJAX, если браузер поддерживает File API - developer.mozilla.org/en/using_files_from_web_applications

Brett Caswell
29 октября 2015 в 14:54
0

это довольно старый ответ, но он немного вводил в заблуждение. IE изначально поддерживал XHR еще в IE7, и поддерживал его через ActiveX еще в IE5. w3schools.com/ajax/ajax_xmlhttprequest_create.asp. Практический способ сделать это определенно заключался в нацеливании на компоненты вспышки (ударной волны) или развертывании элемента управления Flash / ActiveX (Silverlight). Если вы можете создать запрос и обработать ответ через javascript, это ajax ... хотя, как уже говорилось, ajax является синонимом xhr, но сам по себе не описывает механизм / компоненты подчеркивания, которые доставляют / обменивают полезную нагрузку.

Oli
29 октября 2015 в 15:34
4

@BrettCaswell Я не говорил, что AJAX / XHR невозможно, просто невозможно было опубликовать файл с ними в старых, но вечно существующих версиях IE. Это было и остается полностью верным.

avatar
Mattias
3 октября 2008 в 10:36
104

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


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

Alleo
3 ноября 2011 в 18:57
18

Небольшое замечание: в последних версиях chrome и firefox это возможно, coderhelper.com/questions/4856917/…