LINUX.ORG.RU

HTML5 загрузка файлов: что у меня не так?


0

0

Всем доброго времени суток!

Нужен модуль для загрузки фотографий на сервер. Нашел прикольную реализацию с использованием HTML5:

http://habrahabr.ru/blogs/webdev/109079/

Ссылка с исходниками:

http://safron.su/playground/html5uploader/full.zip

Скачал, поставил, но - не рабтает! Файлы выбирает, а при нажатии на закачку ничего не происходит.

Один баг нашел - у меня Opera 11.50, а она не поддерживает XMLHttpRequest2, так что все строки где встречается 'xhr.upload' (файл uploaderObject.js) нужно убрать (с головой, конечно). Для простоты вставил функцию uploadFile(file, url) из текста статьи (она отличается от того, что автор положил в исходники). Все равно не работает.

Вот ключевые точки кода:

interface.js - нажимаем на кнопку «Загрузить»

$("#upload-all").click(function() {

    imgList.find('li').each(function() {

        var uploadItem = this;
        var pBar = $(uploadItem).find('.progress');
        log('Начинаем загрузку `'+uploadItem.file.name+'`...');
						
        uploadFile(uploadItem.file,'./upload.php');

        });
    });

uploaderObject.js

function uploadFile(file, url) {
  
  var reader = new FileReader();
 
  reader.onload = function() {    
    var xhr = new XMLHttpRequest();    
    
//     xhr.addEventListener("progress", function(e) {
//       if (e.lengthComputable) {
//         var progress = (e.loaded * 100) / e.total;
//         /* ... обновляем инфу о процессе загрузки ... */
//       }
//     }, false);
//     
    /* ... можно обрабатывать еще события load и error объекта xhr.upload ... */
		xhr.onprogress=function(e) {
			if (e.lengthComputable) {
				var progress = (e.loaded * 100) / e.total;
        /* ... обновляем инфу о процессе загрузки ... */
				console.log("A progress...\n");
      }
    };
 
			
    xhr.onreadystatechange = function () {
      if (this.readyState == 4) {
        if(this.status == 200) {
          /* ... все ок! смотрим в this.responseText ... */
					console.log("The status is Ok.\n");
        } else {
          /* ... ошибка! ... */
					console.log("The status is NOT Ok.\n");
        }
      }
    };
    
    xhr.open("POST", url);
    var boundary = "xxxxxxxxx";    
    // Устанавливаем заголовки
    xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
    xhr.setRequestHeader("Cache-Control", "no-cache");    
    // Формируем тело запроса
    var body = "--" + boundary + "\r\n";
    body += "Content-Disposition: form-data; name='myFile'; filename='" + file.name + "'\r\n";
    body += "Content-Type: application/octet-stream\r\n\r\n";
    body += reader.result + "\r\n";
    body += "--" + boundary + "--";
		console.log("Ready to send file '"+file.name+"'...\n");
    if(xhr.sendAsBinary) {
      // только для firefox
      xhr.sendAsBinary(body);
    } else {
      // chrome (так гласит спецификация W3C)
      xhr.send(body);
    }
  };
  // Читаем файл
  reader.readAsBinaryString(file);
};

В upload.php я вообще не понимаю что писать. У автора там какой-то бред, не предполагающий сохранение файла. Я сделал вот это:

$uploaddir = getcwd();
$uploadfile = $uploaddir.basename($_FILES['file']['name']);

move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile);

Результатом выполнения являются фразы «Начинаем загрузку...» для каждого из двух файлов, два сообщения «The status is Ok.» и два «Ready to send file XXX...». Сетевой активности нет!

У меня в голове полная чехарда. Подскажите, что не так?

★★★★★

На сях пойдет? Могу выложить (правда, не дописал еще индикатор процесса загрузки).

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от stevejobs

stevejobs
Файл-то загружается?
Нет загрузка даже не начинается (смотрю на сетевой монитор). В этом и проблема.

Eddy_Em
На сях пойдет? Могу выложить (правда, не дописал еще индикатор процесса загрузки).
Очень интересно! Выложи пожалуйста!

RR
http://www.plupload.com/example_custom.php
Тоже смотрю в эту сторону. Но хочется разобраться в принципе, что именно у меня не так! Более того, plupload рассказал мне что у меня нет поддержки HTML5, хотя это немного не корректно: у меня есть поддержка XMLHttpRequest но нет поддержки XMLHttpRequest 2 . Хочется освоить XMLHttpRequest. Что у меня не так в коде?

INFOMAN
http://wiki.nginx.org/HttpUploadProgressModule
Хостинг внешний, установливать дополнительные модули возможности нет!

Kroz ★★★★★ ()
Ответ на: комментарий от Kroz

Нет загрузка даже не начинается (смотрю на сетевой монитор). В этом и проблема.

посмотри еще в то место, куда он должен копироваться :) Иногда сетевой монитор не работает. Поэтому и спросил, «копируется ли файл», а не «есть ли активность на сетевом мониторе»

stevejobs ★★★★☆ ()
Ответ на: комментарий от stevejobs

> посмотри еще в то место, куда он должен копироваться :)

Файла нет

Kroz ★★★★★ ()
Ответ на: комментарий от Eddy_Em

Да, загрузку больших файлов еще не реализовал (для этого нужно будет резать файл на куски на стороне клиента, передавать на сервер по кускам, а там контролировать поступление всех кусков и собирать обратно).

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

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

stevejobs ★★★★☆ ()
Ответ на: комментарий от stevejobs

Просто я начал с подхода «грузим файл любого размера». А потом оказалось, что больше 2ГБ нельзя. Ну и еще оказалось, что файл все равно сначала целиком помещается в оперативку. В общем, с этим делом у разработчиков большой косяк.

Сейчас вот хочу вебсокеты помучить. Вполне возможно, что с их помощью получится файл любого размера сохранять (лишь бы средствами javascript'а это можно сделать).

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

> В общем, с этим делом у разработчиков большой косяк.

тоже пишут из предположения «два гигабайта хватит на всё» :(

Сейчас вот хочу вебсокеты помучить.


отпишись о результатах :) тэги: история успеха, я_пиарюсь, нестартап

stevejobs ★★★★☆ ()
Ответ на: комментарий от Eddy_Em

Спасибо!

Просмотрел - пока сложно (сам С знаю нормально). Но я планирую разобраться как на С писать server-side - там мне очень пригодятся твои наработки.

Kroz ★★★★★ ()
Ответ на: комментарий от stevejobs

Боюсь, пока истории успеха рассказывать рано: стандарта еще нет, и каждая следующая версия браузеров может поддерживать какой-нибудь новый протокол вебсокетов. Так что - поковыряться пока можно, но о чем-то конечном говорить еще рано.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Kroz

Да там надо лишь cmake . ; make; make install (от рута, либо указать cmake'у, куда библиотеку ставить). Но пути будут стандартными. Лучше подредактировать файл run.

Затем включаем библиотечку в свои файлы, как в примерах в директории src.

Например, весь CGI аутентификации и управления пользователями укладывается в 33 строчки.

Eddy_Em ☆☆☆☆☆ ()

FileReader афаик работает только в хроме и гекке. Ну и в 10м ИЕ вроде бы в планах есть: https://developer.mozilla.org/en/DOM/FileReader

Вообще проблема совместимой со всеми браузерами асинхронной загрузки файлов в http все еще весьма актуальна.

Единственный 100% работающий (во всех мейнстримных браузерах) способ: создавать скрытый ифрейм, копировать туда форму, дергать ей submit, после чего парсить ответ сервера.

Все остальное не будет работать либо тут либо там.

ynn ()
Ответ на: комментарий от stevejobs

>Мне однажды на собеседовании на php-кодера за такое минус поставили.

Жесть

pi11 ★★★★★ ()
Ответ на: комментарий от INFOMAN

Например?

Я иногда читаю nginx-ru, там 70% проблем было из-за сторонних модулей, в большинстве случает именно из-за этого. Можешь пошуршать по архивам. Поэтому при возникновении проблем Сысоев первым делом спрашивет какие сторонние модули вкомпилены.

true_admin ★★★★★ ()
Ответ на: комментарий от stevejobs

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

Vit ★★★★★ ()
Ответ на: комментарий от stevejobs

Плюс нужно помнить, что дебильный веб-сервер помещает буфер целиком в оперативку, поэтому выделение еще одного такого же буфера памяти чревато переполнением в 2 раза быстрей :)

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Vit

Прошу прщения, но предлагаю вспомнить вопрос этой темы: как правильно передать (на клиенте) и принять (на сервере) файл средствами XMLHttpRequest? В том примере который описан в первом сообщении - что не так? Что нужно исправить/добавить? Какой должна быть серверная часть?

Неужели никто не пользовалася XMLHttpRequest?

Kroz ★★★★★ ()
Ответ на: комментарий от Kroz

Используйте любой «файлопринимающий» алгоритм. Вот если вы передаете файл по частям - вот тогда будут небольшие сложности (может быть, когда-нибудь я этот алгоритм тоже реализую - пока что у меня период лени).

Eddy_Em ☆☆☆☆☆ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.