Грузите
апельсины бочками.
Есть у меня
демка, загрузка файлов чанками на сервер.
Суть в том, что раз чанками, то файлы
могут быть любого размера, лишь бы место
на диске было.
Вообще-то этих
поделок у меня уже порядком накопилось,
но тут я про одну конкретную расскажу:
HTML5 FileAPI + Node.js
+ Socket.io
Внезапно,
понадобилось вывести аппликуху в люди.
Одному хорошему человеку надо было дать
возможность передать файл. Файл такого
размера, что в электропочту не лезет.
Всякие яндекс-диски и прочие дропбоксы
этот человек, в силу почтенного возраста,
понимать не хочет. Тут я и вспомнил про
VCU.
Достал аппликуху
с чердака, отряхнул от пыли, засадил за
reverse proxy, отягощенный HTTPS и, какая
неожиданность, ничего не работает.
Забегая вперед,
скажу, что проблем была целая пачка:
начиная с нежелания вебсокетов работать
через https прокси и заканчивая некоторыми
изменениями в реализации FileAPI в разных
браузерах.
Проблема
первая. Надо заставить вебсокеты работать
позади https reverse proxy.
Прокси типа
такого:
# /etc/apache2/sites-available/rover-ssl.conf ... <Location /node/vcu/> Order allow,deny allow from all AuthType Basic AuthUserFile /home/valik/.htpasswd AuthName "Alwaysglum restricted services" Require valid-user ProxyPass http://localhost:8080/ </Location> ... |
Код в app.js,
который прекрасно работает в тепличных
лабораторных условиях:
io = require('socket.io').listen(app)
требуется заменить на более изощренный:
io = require('socket.io').listen(app, {'transports': ['polling']})
Почему так и никак иначе, сами догадайтесь.
Теперь второй
файл (вся аппликуха состоит из двух
файлов), index.html.
Подключение
скрипта, меняем вот это:
<script src="/socket.io/socket.io.js"></script>
на более другое:
<script src="socket.io/socket.io.js"></script>
Абсолютные пути для лохов.
И меняем код
создания сокета с примитивного
var socket = io.connect();
на более специфичное:
var socket = io.connect( 'https://alwaysgloom.sytes.net', {path: '/node/vcu/socket.io'});
Теперь вебсокеты
работать будут.
Осталось решить
проблемы совместимости FileAPI в разных
браузера.
Если вкратце,
то раньше чтение файла браузером с диска
было
fileReader.readAsBinaryString(blob);
а стало
fileReader.readAsArrayBuffer(blob);
Что самое
удивительное, на сервере в Node.js данные
приходят в виде объекта Buffer в обоих
случаях! Хотя, казалось бы, очевидно,
что должен приходить ArrayBuffer, если клиент
засылает ArrayBuffer. Я на этой очевидности
потерял пару вечеров, пробуя разные
варианты преобразований ArrayBuffer → Buffer.
В итоге, по
неясной причине, серверный код править
пришлось только в части вызова функций
fs.write. Там тоже что-то поломалось.
Конечный
вариант использования fs.write выглядит
как-то так:
//fs.write(fd, buffer, offset, length[, position], callback) fs.write(fObj.fHandle, fObj.bytesBuf, 0, fObj.bytesBuf.length, null, function(err, written, buffer) { ...
Полностью все
тонкости можно рассмотреть тут
original post http://vasnake.blogspot.com/2015/06/upload-files-by-chunks.html
Комментариев нет:
Отправить комментарий