Как отправить один файл из одного клиентского браузера в другой, не сохраняя его на сервере (node.js), используя html5 и File API

Мне нужно отправить файл из одного клиентского браузера в другой, не сохраняя его на сервере (node.js). Как мне это сделать с помощью HTML5 и File API?

Собственно реализовано решение:

Окончательное решение выглядит так:

  1. При раздаче клиент получает файл из input[type=file]

  2. Файловый массив содержит ключ, хранящий файловый объект. Используйте метод slice/mozSlice, чтобы разделить его на части, чтобы Object.slice возвращал объект Blob.

  3. С помощью FileReader Blob можно считывать в необработанные двоичные данные или данные в кодировке base64. FileReader реализует readAsDataURL(blob) для чтения в base64 и readAsBinaryString(blob) для чтения в необработанные двоичные данные. См. событие FileReader onloadend, чтобы получить доступ к данным, считанным из большого двоичного объекта.

  4. Вы должны реализовать логику для вычисления количества фрагментов в соответствии с размером фрагмента (обычно 1024 * 64) и начальной/конечной позицией следующего фрагмента, чтобы получить фрагменты точно такого же размера.

  5. Закодированные данные отправляются через socket.io на node.js, где единственная логика на стороне сервера заключается в отправке полученных данных на грушу, также подключенную через socket.io.

  6. Думаю, самое интересное - собрать все эти фрагменты вместе в большой двоичный объект в клиентском браузере Pear. Создание BLOB-объекта из необработанных двоичных данных приведет к неправильному размеру BLOB-объекта и, как следствие, к неправильному размеру файла. Вот почему мы передаем из сеялки данные в кодировке base64.
    Декодирование может стать проблемой, поскольку мы должны реализовать его самостоятельно.

    function decode64 (data) {
        var mimeString = data.split(',')[0].split(':')[1].split(';')[0],
        // remove all chars before ','
        byteString = atob(data.split(',')[1]),
        // if BlobBuilder available
        ab = new ArrayBuffer(byteString.length),
        ia = new Uint8Array(ab);
    
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
        blob    = new Blob([ia], {'type' : (mimeString) });
    return blob;
    }
    

После декодирования данных в блоб мы должны поместить их в массив, содержащий другие декодированные фрагменты. 7. Создайте BLOB-объект из массива фрагментов, декодированных в BLOB-объекты, что-то вроде этого

new Blob (array_of_decoded_blobs_returned_by_decode64_function, {type:'mime-type'})

Используя файловый API, записывайте большие двоичные объекты в файл или делайте все, что хотите.


person antiplayer    schedule 28.02.2013    source источник
comment
Только что нашел это, вы можете прочитать его. googleblog.blogspot.sg/ 2013/02/   -  person Diodeus - James MacFarlane    schedule 01.03.2013
comment
Это супер вопрос с решением!! Я долго и упорно искал что-то подобное. Удалось ли вам передать его одноранговой сети без какого-либо реле? Интересно, есть ли шанс получить копию кода, который вы написали? (Если он не является конфиденциальным?) Это будет огромной помощью.   -  person iAteABug_And_iLiked_it    schedule 12.06.2013
comment
а также в 5 вы все еще отправляете данные на сервер, а не напрямую другому узлу, потребляя (потенциально тонны) пропускную способность ... как вы обошли это? Благодарность   -  person iAteABug_And_iLiked_it    schedule 12.06.2013


Ответы (2)


Веб-сокеты - единственный способ, которым я могу это представить, и вам все равно понадобится прокси-сервер на стороне сервера.

См.: Разрешают ли веб-сокеты связь p2p (браузер-браузер)?

person Diodeus - James MacFarlane    schedule 28.02.2013
comment
Спасибо за вашу помощь. Что касается предоставленной вами ссылки, нет реальной рабочей реализации для одноранговой связи с веб-сокетами или любой другой спецификацией. Они предлагают использовать сервер, обрабатывающий соединения от разных клиентов, хотя я понятия не имею, как передать файл с двумя клиентами, подключенными через веб-сокет, без необходимости сохранять его на стороне сервера. Так что мне нужна дополнительная помощь - person antiplayer; 01.03.2013
comment
Возможно, вам не нужно СОХРАНЯТЬ его на сервере, но вы сможете транслировать его через него. - person Diodeus - James MacFarlane; 01.03.2013
comment
Любые идеи о технике потоковой передачи с js? Я не мог найти способ загрузить сохранение файла в поток или что-то в этом роде. - person antiplayer; 01.03.2013
comment
Я предполагаю, что вам нужно сначала преобразовать его в base64. - person Diodeus - James MacFarlane; 01.03.2013
comment
Решено. Обновил вопрос. Спасибо за помощь @Diodeus - person antiplayer; 06.03.2013

Проверьте webrtc. Вы можете напрямую отправить файл в браузер. Сервер сообщает только одному клиентскому браузеру об «адресе» другого клиентского браузера.

person karaxuna    schedule 11.09.2013