Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 20.12.2020, 09:51
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,762

Непонятки с кодировкой в URLSearchParams
Ситуация такая. Есть есть очень старый CGI скрипт, написанный на C.
Работает как швейцарские часы, менять его никто не хочет (да и не может). У него одна проблема - он работает в кодировке cp1251. Т.е в этой кодировке ему надо давать русские буквы.
Сейчас там надо внести изменения в клиентскую часть, что бы использовать ajax (fetch) вместо обычной смены страницы, как при form submit.
Решил формировать строку параметров с помощью URLSearchParams
Перевести значение параметра запроса из юникода в cp1251 не проблема, но дальше начинаются непонятки.
Вот такой тестовый пример

<script>
let us = new URLSearchParams()
us.append('keyw', 'áåëûé êðîëèê')   //Это "белый кролик" в cp1251
let s = us.get('keyw')
console.log(s)              // áåëûé êðîëèê   Правильно
let cp =[...s].map (c => c.codePointAt(0))  // Получаю кодовые точки
console.log(cp)             // [225, 229, 235, 251, 233, 32, 234, 240, 238, 235, 232, 234]  Правильно
let sus = us.toString()
                         // keyw=%E1%E5%EB%FB%E9+%EA%F0%EE%EB%E8%EA   Так должно быть
console.log(sus)        // keyw=%C3%A1%C3%A5%C3%AB%C3%BB%C3%A9+%C3%AA%C3%B0%C3%AE%C3%AB%C3%A8%C3%AA   ????
</script>


Почему URLSearchParams.toString как то меняет кодировку?
Почему код 225 вместо %E1 превращается в %C3%A1 ?

Есть какие нибудь идеи, что с этим делать?

Последний раз редактировалось voraa, 20.12.2020 в 09:54.
Ответить с цитированием
  #2 (permalink)  
Старый 20.12.2020, 10:52
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,144

Сообщение от voraa
Есть какие нибудь идеи, что с этим делать?
http://xpoint.ru/know-how/JavaScript/PoleznyieFunktsii

// Инициализируем таблицу перевода
var trans = [];
for (var i = 0x410; i <= 0x44F; i++)
  trans[i] = i - 0x350; // А-Яа-я
trans[0x401] = 0xA8;    // Ё
trans[0x451] = 0xB8;    // ё

// Сохраняем стандартную функцию escape()
var escapeOrig = window.escape;

// Переопределяем функцию escape()
window.escape = function(str)
{
  var ret = [];
  // Составляем массив кодов символов, попутно переводим кириллицу
  for (var i = 0; i < str.length; i++)
  {
    var n = str.charCodeAt(i);
    if (typeof trans[n] != 'undefined')
      n = trans[n];
    if (n <= 0xFF)
      ret.push(n);
  }
  return escapeOrig(String.fromCharCode.apply(null, ret));
}
let us = `keyw=${escape('áåëûé êðîëèê')}`
console.log(us)
Ответить с цитированием
  #3 (permalink)  
Старый 20.12.2020, 11:28
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,762

рони,
В ручную я и сам перекодирую.
Тут проблема, что бы была возможность использовать URLSearchParams, что бы не надо было вручную формировать строку запроса.
Там идет некоторая работа с параметрами. Если задан такой и такой, то вместо них включить в строку другой и т.п. URLSearchParams удобен для таких целей.
До меня дошло, как он поступает. Он, гад, код E1 переводит в utf-8 -это действительно C3A1 а потом уже кодирует в %C3%A1

Наверно придется писать аналог для URLSearchParams с необходимым функционалом (set, get, toString...)
Ответить с цитированием
  #4 (permalink)  
Старый 20.12.2020, 11:59
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,592

Современные разрабатыватели стандартов болт положили на все кодировки кроме utf-8. У тебя и fetch из коробки не способен кодировки различать.
Так что либо пилить костыли на костылях, либо работать по классике XMLHttp + вручную составление get параметров.
__________________
29375, 35
Ответить с цитированием
  #5 (permalink)  
Старый 20.12.2020, 12:37
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,762

А что делать, если приходится учитывать этот старый скрипт, который никто не хочет переделывать под современные стандарты.
Работает. Хорошо и без ошибок работает много-много лет. И слава Богу.

Сообщение от Aetae
У тебя и fetch из коробки не способен кодировки различать.
В каком смысле и в какой ситуации?

рони,
Вот это вот
var trans = [];
for (var i = 0x410; i <= 0x44F; i++)
  trans[i] = i - 0x350; // А-Яа-я
trans[0x401] = 0xA8;    // Ё
trans[0x451] = 0xB8;    // ё

Не совсем полная таблица.
Вот с чем я сталкивался в реале.
Когда считываешь файл c кодировкой cp1251

let f = new FileReader()
f.readAsText(blob, 'cp1251')

он некоторые символы типа '…︎' (код в cp1251 - x85 в unicode ему соответствуют и x85 и x2026) переводит в x2026. Такая же фигня происходит и с кавычками “︎ ”︎. У них в unicode несколько кодов, и берется не тот, который хотелось бы.
Поэтому при обратном преобразовании это приходится учитывать. Т.е. еще

trans[0x2026] = 0x85;
.....

Последний раз редактировалось voraa, 20.12.2020 в 12:54.
Ответить с цитированием
  #6 (permalink)  
Старый 20.12.2020, 13:44
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,144

voraa,
ок
Ответить с цитированием
  #7 (permalink)  
Старый 20.12.2020, 15:32
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,592

Сообщение от voraa Посмотреть сообщение
В каком смысле и в какой ситуации?
В любой. Проверь сам, он умеет только в utf-8. Нужна другая - будь добр получать ArrayBuffer и использовать TextDecoder.
__________________
29375, 35
Ответить с цитированием
  #8 (permalink)  
Старый 20.12.2020, 16:52
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,762

Сообщение от Aetae
Нужна другая - будь добр получать ArrayBuffer и использовать TextDecoder.
Получать то не сложно.
Я через blob делаю.
Получаю как blob, а потом (new FileReader()).readAsText(blob, 'cp1251')
Из cp1251 в unicod есть средства.
А вот обратно, да еще в виде пригодном для url - проблемы возникают.
Тут запрос бы передать.

Последний раз редактировалось voraa, 20.12.2020 в 16:59.
Ответить с цитированием
  #9 (permalink)  
Старый 20.12.2020, 18:21
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,592

Сообщение от voraa Посмотреть сообщение
Я через blob делаю...


XMLHttp сам всё сделает без boilerplate и оверхэда, так что нахрен fetch в старых сетапах(современные уж на utf-8). А также нахрен его если нужен xml документ, нахрен если нужен жирный json(на текущий момент .json() в fetch все ещё работает сильно медленнее на больших объёмах), нахрен если нужна нормальная перезапись хэдеров...
В общем много когда нахрен.
__________________
29375, 35
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблемы с кодировкой на node.js 6at9l Node.JS 5 19.05.2020 12:16
Отобразить страницу с одной кодировкой на странице с другой кодировкой MrBean Общие вопросы Javascript 24 11.06.2016 22:37
Не могу разобраться с кодировкой. dubrovski Общие вопросы Javascript 4 02.07.2013 21:24
Проблемы с кодировкой... Vladislav AJAX и COMET 1 08.06.2013 22:09
Проблема с кодировкой в скрипте автозаполнения Maratka AJAX и COMET 12 24.01.2009 12:31