API файлов Javascript / HTML5, считывающий последовательные файлы в данные составной формы - PullRequest
4 голосов
/ 19 марта 2011

Я использую HTML5 File API для сбора многокомпонентных данных формы для отправки XHR в веб-сервис. У меня есть все, что работает в FF, который имеет хороший удобный метод getAsBinary (), включенный в их реализацию файлового API. Это была довольно приятная сделка. В основном пошло:

var const;  // constructor
const += headers;
const += field_data;

for(var i = 0; i < files.length; i++)
{
   const += files[i].getAsBinary();
}

sendData(const);

работал как шарм.

Чтобы заставить его работать в Chrome, мне нужно создать объект FileReader, который обрабатывает немного по-другому. Я по сути должен идти:

var const;  // constructor
const += headers;
const += field_data;

var reader = new FileReader();

for(var i = 0; i < files.length; i++)
{
    reader.onload = (function(file)
    {
       const += file.target.result;   // const is not in scope in this anonymous function!
    }
    reader.readAsBinaryString(files[i]);
}

sendData(const);

Что не работает, по двум основным причинам. Во-первых, чтение происходит асинхронно, поэтому к тому времени, когда оно попадает в функцию sendData (), данные файла не записываются в переменную const. Во-вторых, переменная const находится вне области видимости внутри обработчика reader.onload. Тем не менее, я заново настраиваю код, я, кажется, сталкиваюсь с одним из этих препятствий, и я изо всех сил пытаюсь найти изящный способ справиться с ним.

Есть предложения?

Ответы [ 2 ]

3 голосов
/ 19 марта 2011

То, что вам нужно сделать, - это заставить обработчики «загрузки» считывателя проверить, запущены ли они последними.Когда это происходит, тогда этот обработчик может вызвать «sendData ()».

var const;  // constructor
const += headers;
const += field_data;

var reader;
var finished = 0;
for(var i = 0; i < files.length; i++)
{
    reader = new FileReader();
    reader.onload = function(file)
    {
       const += file.target.result;
       if (++finished === files.length)
         sendData(const);
    };
    reader.readAsBinaryString(files[i]);
}

(я не до конца понимаю детали того, как эта накопленная «const» вещь будет корректно превращаться в составной MIME-объект,но я предполагаю, что вы делаете :-) Кроме того, и это, вероятно, важно: я думаю вам, вероятно, нужно создать новый экземпляр "FileReader" для каждого файла.Я закодировал это таким образом (на самом деле я только что отредактировал это), но это может быть неправильно, так как я не очень знаком с API и его семантикой.

0 голосов
/ 18 мая 2011

Рассматривали ли вы xhr.send(FormData)?Смотрите мой ответ здесь: загрузка в php $ _FILE из расширения chrome

Вы можете добавлять файлы в объект FormData и отправлять их через xhr.Браузер строит для вас запрос из нескольких частей.Я считаю, что это доступно в FF4 и было в Chrome в течение некоторого времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...