Возврат двоичного файла Sinatra для msgpack — проблема с кодировкой / символы где-то конвертируются?

#javascript #ruby #character-encoding #sinatra #msgpack

#javascript #ruby #кодировка символов #sinatra #msgpack

Вопрос:

В настоящее время я пытаюсь вернуть msgpack http://msgpack.org / из сервиса ruby sinatra и проанализируйте его с помощью javascript. Я использую библиотеку JavaScript, найденную здесь: https://github.com/uupaa/msgpack.js / (хотя я не думаю, что это имеет отношение к данному вопросу).

У меня есть служба sinatra, которая выполняет следующие действия, используя драгоценный камень msgpack:

 require 'sinatra'
require 'msgpack'

get '/t' do
  content_type 'application/x-msgpack'
  { :status => 'success', :data => {:one => "two", :three => "four"}}.to_msgpack
end
 

У меня есть javascript, который читает его следующим образом:

 <script src="js/jquery.js"></script>
<script src="js/msgpack.js"></script>
<script type="text/javascript">

    function r() {
        $.ajaxSetup({
            converters: {
                "text msgpack": function( packed ) {
                    if(packed != '') {
                        unpacked = msgpack.unpack(packed);
                        return unpacked;
                    }else{
                        return ''
                    }
                }
            }
        });

        $.ajax({
            type: "GET",
            url: "/t",
            dataType: "msgpack",
            success: function(data) {
                alert(data)
            }
        })  
    }
    $(document).ready(r)
</script>
 

Проблема в том, что, когда я получаю данные обратно, многие символы были преобразованы из их серверной версии в 0xfffd .

Затем я попробовал два варианта:

 content_type 'application/octet-stream'
 

и

 content_type 'application/octet_stream', :charset => 'binary'
 

на стороне сервера. Первое ничего не изменило, но второе приблизилось, оставив большую часть сообщения нетронутой, за одним исключением: первый символ был преобразован из 0x82 в 0x201a .

Я подозреваю, что существует комбинация кодировок / типов контента, которая исправила бы это, но я еще не пробовал. Я также всегда мог бы вернуться к Base64, но сначала я хотел бы понять, что нужно для того, чтобы заставить его работать без Base64.

Комментарии:

1. Какую версию Ruby вы используете?

2. ruby 1.9.2p290 (2011-07-09 редакция 32553) [i686-linux] — на 64-битной версии ubuntu 10.10. Также я использую Sinatra 1.2.6 с Rack 1.3.2, размещенным с использованием thin 1.2.11.

3. Тем не менее, я просто попытался получить ответ с помощью net-http — не похоже, что преобразование происходит на стороне сервера.

4. Я обновил ответ, чтобы отразить это.

Ответ №1:

0x82 находится LOW QUOTATION MARK в Latin1, 0x201a является тем же символом в UTF-16. Посмотрите, как ваши библиотеки справляются с кодированием, скажите им, чтобы они использовали двоичную кодировку и не пытались выполнять какие-либо преобразования между кодировками.

UTF-16 пахнет JavaScript. Если вы используете jQuery, взгляните на http://blog.vjeux.com/2011/javascript/jquery-binary-ajax.html .

Комментарии:

1. Итак, теперь я просто пытаюсь заставить его работать без jQuery (используя отправленную вами ссылку, а также developer.mozilla.org/En/XMLHttpRequest /… ). Однако, чем больше я углубляюсь в это, тем больше кажется, что лучшим решением является просто преобразование в Base64, чтобы было меньше проблем с совместимостью с браузером… Я нахожусь на относительно незнакомой территории, поэтому я считаю, что она также будет более удобной в обслуживании. — Спасибо за помощь!

2. На самом деле реальная проблема заключается в том, что немногие разработчики библиотек знакомы с этой проблемой. В наши дни кодировки сильно кусаются. 🙂

3. Sinatra не затрагивает кодировку тела.