Есть задача - реализовать создание комбинированного изображение (фон, несколько надписей с тенями) и отправить его в вк на стену сообщества вместе с текстом. Это условие заказа - сделать такой редактор.
Теперь я от себя ещё хочу, чтобы работало в Opera 11-12 (вид теней в разных браузерах существенно отличается, во всяком случае в Опере и в Хроме точно, и калибровать удобнее под Оперу, поскольку я всё время работаю в ней). Но в Opera 11 нет XHR2 и FormData, соответственно, отправка файлов нативно - не работает.
На данный момент я реализовал создание картинки. Также реализовал в тестовых целях экспорт функцией toDataURL() изображения в Base64 строку и отправку её на свой же сервер как поле обычной формы (x-www-form-urlencoded) с последующим декодированием. На этом этапе всё супер.
Далее я попытался составить POST запрос методом multipart/formdata, прочитал стандарт, нашёл примеры, вроде сделал. Сначала возникла проблема, что никак не получалось посчитать Content-Length - правильное значение почему-то не подходило, но потом оказалось, что если его не указать вообще - запрос проходит нормально.
Но теперь я упёрся в очень странный момент. Файл отправляется, PHP его видит. У меня есть строка, полученная из toDataURL() обрезанием начала, и если я её посылаю на сервер, и декодирую из Base64 на стороне PHP - всё норм, картинка получается корректной. При этом у меня есть две реализации функции декодирования из Base64, написанные на JS - одну писал я сам давно, вторая взята из сети. Обе выдают один и тот же результат (во всяком случае, по длине). И эта длина совпадает с размером файла, полученным после конвертации на сервере. Но! Как только я отправляю декодированную строку (обычным xhr.send) - на сервер приходит совсем не то. Причём при отправке разными браузерами размер разный. Но всегда в результирующем файле получается какая-то ерунда.
56f8cc7d7d45f.png 976795 2016.03.28 09:17
56f8ccfa326dd.png 650807 2016.03.28 09:19
56f8ced2903ec.png 762761 2016.03.28 09:27
Здесь первый файл отправлен Оперой версии 11, второй - отправлен ей же в Base64 и декодирован на сервере средствами PHP, третий - отправлен Хромом свежей версии. Из них корректным является лишь второй... Причём длины очень отличаются. Я как бы догадываюсь, что проблема в том, что браузер думает, что это текст, а там бинарные данные. Но сам HTTP протокол их не запрещает - с чего бы браузеру их коверкать? Возможно, браузер пытается преобразовать данные в другую кодировку?
Посмотреть результат декодирования из Base64 на клиенте не могу - консоль не хочет его выводить =)
Пытаться делать diff по таким объёмам нетекстовых данных?
Подскажите пожалуйста, что происходит, как с этим бороться, и можно ли.
Хочется получить отправку изображения на сервер на чистом JS без серверного прокси, и желательно малой кровью. Тем более, я так понимаю, цель почти достигнута - видимо остались какие-то мелкие проблемы с кодировками...
UPDATE: Firefox всё же выводит на консоль результат преобразования, где вместо половины символов - квадратики. Но толку от этого мало... Самое нелепое - все браузеры после преобразования получают разные строки. 758708 символов в Firefox, 507068 в Chrome, 650807 в Opera. И верный результат (как при серверном декодировании) - только в Opera (внезапно). Впрочем, в момент отправки что-то происходит, и на сервер всё равно приходит уже не то.
Мне нужно отправить файл именно стандартным образом (вк его за меня из base64 раскодировать не будет), но при этом не заставлять заказчика загружать картинку на комп и выбирать её же в файловый инпут формы...
UPDATE2: если задача не решаема, подскажите решение хотя бы для новых браузеров. XHR2+FormData - отправит как обычный файл картинку? С другой стороны, если для универсальности всё равно придётся писать PHP скрипт, сохраняющий картинку во временный файл, и отправляющий её через cURL - FormData уже и не нужен... Интересно, возможно ли для нормальных браузеров использовать FormData, а для старых Опер придумать какой-то хак, приводящий строку к такому виду, чтобы после "замены", когда она портится, она как раз стала нормальной. Но для этого видимо анализировать сами полученные файлы нужно?)