2017-01-03 1 views
1

J'ai rencontré un problème, malheureusement, je n'ai pas trouvé de solution correcte: j'ai besoin de décoder l'URL qui est encodée avec windows-1251 (cp1251) .Décoder une chaîne windows-1251 (cp1251) encodée par url avec JavaScript

Je sais qu'il existe des méthodes theese - decodeURI() et decodeURIComponent(), mais ils travaillent pour UTF-8 seulement (comme je l'ai compris). Une solution que j'ai trouvée utilise des méthodes obsolètes escape() et unescape().

Par exemple, il y a séquence:

% EF% F0% EE% E3% F0% E0% CE% CE% E8% F0% EE% E2% E0% ED% E8% E5 (par défaut)

Les méthodes decodeURI() et decodeURIComponent() provoqueront une exception.

Seront reconnaissants pour l'aide.

+0

Ces méthodes sont déconseillés, car ils ne prennent pas en charge Unicode. Je ne dirais pas que c'est un problème dans votre cas. –

+0

@ ÁlvaroGonzález la décision était comme ceci decodeURIComponent (unescape ('% EF% F0% EE% E3% F0% E0% EC% EC% E8% F0% EE% E2% E0% ED% E8% E5')) Mais, le résultat est ïðîãðàììèðîâàíèå - séquence de ISO-8859-1 – Romanzhivo

+0

Dans quel environnement êtes-vous, navigateur ou nodejs (ou autre chose)? – Bergi

Répondre

2

Il n'y a pas de prise en charge intégrée pour le schéma de codage en pourcentage avec les jeux de caractères hérités dans le navigateur, pour autant que je puisse voir. Vous devrez:

  1. trouver les échappements% représentant les octets gagnant-1251,
  2. décoder les octets gagnant-1251 aux caractères correspondants (JS String)

est inférieure à un façon de le faire. Pour le # 1, je suppose que seules les échappées majuscules de 3 caractères ont besoin de décodage, et le reste de la chaîne est déjà ASCII, donc j'utilise simplement inputStr.replace(/%([0-9A-Z]{2})/g,replacerFunction) pour cela.

Pour le décodage actuel, vous avez besoin d'un mappage des caractères win-1251 vers les caractères JS. Dans l'exemple ci-dessous, je construis le mapping en utilisant TextDecoder.decode() API, juste pour m'amuser (et au cas où quelqu'un trouverait cette réponse en essayant de convertir entre différents jeux de caractères dans JS). (Note: il n'est pas supporté universellement à ce jour - seul Gecko/Blink le supporte).

Il y a aussi https://github.com/mathiasbynens/windows-1251, que je voulais initialement utiliser pour cette réponse, mais il s'est avéré plus facile de construire la carte de décodage à la main.

var decodeMap = {}; 
 
var win1251 = new TextDecoder("windows-1251"); 
 
for (var i = 0x00; i < 0xFF; i++) { 
 
    var hex = (i <= 0x0F ? "0" : "") +  // zero-padded 
 
      i.toString(16).toUpperCase(); 
 
    decodeMap[hex] = win1251.decode(Uint8Array.from([i])); 
 
} 
 
// console.log(decodeMap); 
 
// {"10":"\u0010", ... "40":"@","41":"A","42":"B", ... "C0":"А","C1":"Б", ... 
 

 

 
// Decodes a windows-1251 encoded string, additionally 
 
// encoded as an ASCII string where each non-ASCII character of the original 
 
// windows-1251 string is encoded as %XY where XY (uppercase!) is a 
 
// hexadecimal representation of that character's code in windows-1251. 
 
function percentEncodedWin1251ToDOMString(str) { 
 
    return str.replace(/%([0-9A-F]{2})/g, 
 
    (match, hex) => decodeMap[hex]); 
 
} 
 

 
console.log(percentEncodedWin1251ToDOMString("%EF%F0%EE%E3%F0%E0%EC%EC%!%E8%F0%EE%E2%E0%ED%E8%E5a"))

+0

Nickolay, merci pour la réponse! Cette décision fonctionne, mais il semble que j'ai trouvé une autre décision. Je ne sais pas, puis-je publier un script, comme il est à partir du site http://www.codenet.ru Cette décision contient une carte et n'ont pas de technologies expérimentales comme TextDecoder.decode() API – Romanzhivo

+0

@Romanzhivo pouvez-vous poster un lien vers la solution trouvée? (Notez que la partie «expérimentale» de mon exemple peut être facilement remplacée par la carte codée en dur.) – Nickolay

+0

Nickolay, je pense que je pourrais, la solution de ce site http://codenet.ru, je l'ai trouvé dans les scripts d'un site et j'ai ajouté quelques modifications et placé dans mon répertoire temporaire http://code.romanzhivo.com/ test/decode-windows-1251.js PS Je ne peux pas lier votre nom dans les commentaires :) – Romanzhivo