Выполнение загрузки JQuery и загрузка файла AJAX

Кажется, я не ясно сообщил о своей проблеме. Мне нужно отправить файл (используя AJAX), и мне нужно получить ход загрузки файла, используя Nginx HttpUploadProgressModule. Мне нужно хорошее решение этой проблемы. Я пробовал с jquery.uploadprogress плагин, но мне приходится переписывать большую часть его, чтобы заставить его работать во всех браузерах и отправить файл с помощью AJAX.

Все, что мне нужно, это код для этого, и он должен работать во всех основных браузерах (Chrome, Safari, FireFox и IE). Было бы даже лучше, если бы я смог получить решение, которое будет обрабатывать несколько загрузок файлов.

Я использую jquery.uploadprogress плагин, чтобы получить ход загрузки файла из NginxHttpUploadProgressModule. Это внутри iframe для приложения facebook. Он работает в firefox, но он не работает в chrome/safari.

Когда я открываю консоль, я получаю это.

Uncaught ReferenceError: progressFrame is not defined
jquery.uploadprogress.js:80

Любая идея, как я это исправить?

Я также хотел бы отправить файл с помощью AJAX, когда он будет завершен. Как это реализовать?

EDIT:
Мне нужно это в ближайшее время, и это важно, поэтому я собираюсь поставить 100 баллов за этот вопрос. Первый человек, ответивший на него, получит 100 баллов.

РЕДАКТИРОВАТЬ 2:
Джейк33 помог мне решить первую проблему. Первый человек, чтобы оставить ответ с тем, как отправить файл с ajax, тоже получит 100 баллов.

Ответы

Ответ 1

Загрузка файлов на данный момент возможна с AJAX. Да, AJAX, а не некоторые дрянные AJAX wannabes, такие как swf или java.

Этот пример может помочь вам: https://webblocks.nl/tests/ajax/file-drag-drop.html

(Он также включает интерфейс перетаскивания/перетаскивания, но это легко игнорируется.)

В основном это сводится к следующему:

<input id="files" type="file" />

<script>
document.getElementById('files').addEventListener('change', function(e) {
    var file = this.files[0];
    var xhr = new XMLHttpRequest();
    (xhr.upload || xhr).addEventListener('progress', function(e) {
        var done = e.position || e.loaded
        var total = e.totalSize || e.total;
        console.log('xhr progress: ' + Math.round(done/total*100) + '%');
    });
    xhr.addEventListener('load', function(e) {
        console.log('xhr upload complete', e, this.responseText);
    });
    xhr.open('post', '/URL-HERE', true);
    xhr.send(file);
});
</script>

(демо: http://jsfiddle.net/rudiedirkx/jzxmro8r/)

Итак, в основном, что это такое - это =)

xhr.send(file);

Где file typeof Blob: http://www.w3.org/TR/FileAPI/

Другой способ (лучше ИМО) - использовать FormData. Это позволяет вам 1) назвать файл, как в форме, и 2) отправить другой материал (файлы тоже), как в форме.

var fd = new FormData;
fd.append('photo1', file);
fd.append('photo2', file2);
fd.append('other_data', 'foo bar');
xhr.send(fd);

FormData делает код сервера более чистым и более обратным (поскольку запрос теперь имеет тот же формат, что и обычные формы).

Все это не экспериментально, а очень современно. Chrome 8+ и Firefox 4+ знают, что делать, но я не знаю ни о каких других.

Вот как я обработал запрос (1 изображение на запрос) в PHP:

if ( isset($_FILES['file']) ) {
    $filename = basename($_FILES['file']['name']);
    $error = true;

    // Only upload if on my home win dev machine
    if ( isset($_SERVER['WINDIR']) ) {
        $path = 'uploads/'.$filename;
        $error = !move_uploaded_file($_FILES['file']['tmp_name'], $path);
    }

    $rsp = array(
        'error' => $error, // Used in JS
        'filename' => $filename,
        'filepath' => '/tests/uploads/' . $filename, // Web accessible
    );
    echo json_encode($rsp);
    exit;
}

Ответ 2

Вот несколько вариантов использования AJAX для загрузки файлов:

UPDATE:. Вот подключаемый модуль JQuery для Несколько загрузки файлов.