Короче, пишу свой прокси-сервер на node.js (это все равно пригодится, но и просто прокси свое применение имеет, мне давно тему спалили, интересно, живо ли это еще)

Прокси на основе методов типа .pipe() мне не подходит – мне надо полные данные через себя пропускать, а так они мимо пройдут. Мне надо скачать данные полностью, обработать и потом отправить.

Написал прокси на сокетах на основе примеров – бьет картинки (скачиваются данные другой длины, чем content-length, причем для маленьких картинок разница меньше, для больших больше)

Переписал на модуле http – все равно бьет, видимость проблемы та же.

Долго ***ся, нигде ничего нет про такую проблему…

Причина – что весь ввод-вывод и с сокетами, и с http – имеет указание кодировки, и даже если ты ее не указываешь (опциональный параметр), там внутри есть какая-то кодировка по умолчанию, и она по умолчанию что-то делает!

То есть, все картинки этой кодировкой обрабатываются как-то и портятся. И это отдельный вопрос, что за хрень – одна кодировка? Тогда должно быть две – кодировка до и после.

Как лечить проблему с кодировкой node.js


Ставим кодировку ‘binary’ – если скачиваем, то до получения данных надо писать что-то вида

var req = http.request(options, function (res) {
res.setEncoding('binary');

А когда отправляешь картинку, надо второй параметр добавлять, вида

response.write(data,'binary');

И оно перестанет лазить в данные, а так било еще и кодировку html, просто я не сразу заметил, сперва на картинках увидел.

И нигде никогда на советах примерах всяких stackoverflow.com и документациях этого нет, что эта работа с кодировкой включена по умолчанию и она все данные портит.

Как это вообще? англоязычным ладно, пофиг на кодировки, но картинки? они приводят такие спокойно примеры кода, которые битые данные берут и отправляют…

Я не профи программер, изобретаю велосипеды. Наверняка вы сейчас найдете тонны прокси с открытым кодом (удовлетворяющие условиям выше), в него надо было просто посмотреть
Поделиться с друзьями
-->

Комментарии (21)


  1. aol-nnov
    13.04.2017 13:47
    +10

    а надо-то было — всего одну строку в документации посмотреть.
    https://nodejs.org/dist/latest-v6.x/docs/api/http.html#http_response_write_chunk_encoding_callback

    By default the encoding is 'utf8'


    1. raveclassic
      13.04.2017 13:52
      +10

      Ну да, обычная история. А воплей-то сразу сколько, какая нода плохая, в utf работает!


      1. euhenio
        13.04.2017 15:07

        если бы ты подписал договор, в котором мелким шрифтом нечно написано… тоже бы небось

        вопли потому, что вот такие умолчания — это не тру.
        Ладно бы заставили меня каждый раз указывать в явном виде кодировку, раз она все равно будет работать.
        Тогда я бы знал, что она работает и ее нужно поменять


      1. dreammaster19
        13.04.2017 15:13

        История стандартная, но и автору спасибо, кому-нибудь пригодится. Единственно — это статься скорее для stackoverflow, а не для хабра


    1. euhenio
      13.04.2017 15:05

      совет читать документацию понятный, но здравый смысл никто не отменял!

      и это ОЧЕНЬ НЕОЧЕВИДНО, что мои, мои данные — кто-то там в промежутке перекодирует
      зло, натурально


      1. aol-nnov
        13.04.2017 15:07
        +1

        здравый смысл как раз состоит в том, чтобы обратиться к документации в самом начале, а не бездумно копипастить с просторов и потом безуспешно искать ответы на стековерфлоу…


        1. euhenio
          13.04.2017 15:10

          нуу… я не бездумно, но первое по времени сильно быстрее. И результат быстро, хоть и проблемы есть.

          но вы сами лично считаете нормальным такие умолчания?
          мне кажется, такие умолчания = зло


          1. aol-nnov
            13.04.2017 15:12

            умолчания во фреймворках/либах/сдк подразумевают принятие и следование разработчиком (пользователем этих фреймворков/либ/сдк) некоторых конвенций.

            Когда он даже не в курсе этого — «ой, я всё» :)


            1. euhenio
              13.04.2017 15:20

              это как /в договоре мелким шрифтом/

              есть очевидные вещи = я кодировку и перекодирование не заказывал использовать, вот и не надо.

              А мне в ответ ссылки на доки ) да, формально вы правы, но это дико неправильно так делать


              1. aol-nnov
                13.04.2017 15:28
                +1

                не совсем верная отсылка к мелкому шрифту, ну да ладно.

                if it hurts, do in often! ;)


        1. euhenio
          13.04.2017 15:11
          -4

          а по мне так здравый смысл состоит не в изучении доков годами, а чтобы сделал и работало.


          1. DexterHD
            13.04.2017 16:41
            +3

            Достаточно потратить пару часов на вдумчивое чтение доков, после чего, чтобы ты не сделал оно будет работать.

            нуу… я не бездумно, но первое по времени сильно быстрее. И результат быстро, хоть и проблемы есть.

            Это очень большое заблуждение, которое с опытом исчезает. Проще, дешевле и быстрее 1 раз вычитать какую-нибудь 100 страничную спецификацию потратив на нее рабочий день и не сталкиваться в будущем с проблемами практически никогда, чем постоянно гуглить стековерфлов и бегло глядеть в доки и костылить годами.


          1. Kanumowa
            13.04.2017 20:11
            -1

            Мне повезло с преподавателем, и он на первом занятии сказал, что в js дефолтная кодировка utf-8, в других яп она может быть другой. И в курсе по ноде я тоже это слышал… Но спасибо, что заострили внимание, т.к. мелочей не бывает и на таких моментах иногда уходит очень много времени.


          1. raveclassic
            13.04.2017 20:27

            Есть такая парадигма ххвп-программирования. Она, конечно, эффективна — быстро, гибко, все дела. Но до первого эпикфейла с намертво лежащим продом, который и поднять-то уже нереально, ибо сделано все не по докам и спекам, а чтобы «сделал и работало».


            1. euhenio
              13.04.2017 20:58

              как переводится ххвп? )

              Да, чтобы сделал и работало — это наше всё.
              Можно вместо этого, конечно, делать и получать зарплату, за процесс


              1. grossws
                13.04.2017 21:28

                хренак-хренак и в продакшн, скорее всего


                1. euhenio
                  13.04.2017 22:24

                  буду теперь использовать это слово! ххвп


  1. bano-notit
    13.04.2017 21:43
    +2

    Стандартная проблема для человека, который не читает доки...


    1. euhenio
      13.04.2017 22:30
      -3

      ты будешь читать доки годами, продолжай


      1. bano-notit
        13.04.2017 22:38
        +1

        Ну допустим уже читаю годами, и вот не случалось такой фигни, чтобы я чего-то просто не прочитал. Были и доки старые, были и баги в реализации самой либы/фреймворка/платформы, но так, чтобы я тупо не прочёл доки и полез куда-то, нет.


  1. vird
    14.04.2017 15:08
    +1

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

    Некоторые библиотеки идут дальше и выдают буфер сразу (и иногда даже не имеют опции кодировки), который нужно еще преобразовать в строку через toString. Это чуть более интуитивно, но менее производительно т.к. больше памяти и лишнее копирование. Но да, так проще программисту. Ты сначала выстреливаешь себе в ногу (если хочешь строку), и сразу фиксишь, не лазя в документацию.

    API node.js сделано всё-таки с упором на производительность, потому вот так.