Actually, everything is typically stored as Unicode of some kind internally, but lets not go into that. I'm assuming you're getting the iconic "?¥?¤??" type strings because you're using an ISO-8859 as your character encoding. There's a trick you can do to convert those characters. The escape
and unescape
functions used for encoding and decoding query strings are defined for ISO characters, whereas the newer encodeURIComponent
and decodeURIComponent
which do the same thing, are defined for UTF8 characters.
escape
encodes extended ISO-8859-1 characters (UTF code points U+0080-U+00ff) as %xx
(two-digit hex) whereas it encodes UTF codepoints U+0100 and above as %uxxxx
(%u
followed by four-digit hex.) For example, escape("?") == "%E5"
and escape("あ") == "%u3042"
.
encodeURIComponent
percent-encodes extended characters as a UTF8 byte sequence. For example, encodeURIComponent("?") == "%C3%A5"
and encodeURIComponent("あ") == "%E3%81%82"
.
So you can do:
fixedstring = decodeURIComponent(escape(utfstring));
For example, an incorrectly encoded character "?" becomes "?¥". The command does escape("?¥") == "%C3%A5"
which is the two incorrect ISO characters encoded as single bytes. Then decodeURIComponent("%C3%A5") == "?"
, where the two percent-encoded bytes are being interpreted as a UTF8 sequence.
If you'd need to do the reverse for some reason, that works too:
utfstring = unescape(encodeURIComponent(originalstring));
Is there a way to differentiate between bad UTF8 strings and ISO strings? Turns out there is. The decodeURIComponent function used above will throw an error if given a malformed encoded sequence. We can use this to detect with a great probability whether our string is UTF8 or ISO.
var fixedstring;
try{
// If the string is UTF-8, this will work and not throw an error.
fixedstring=decodeURIComponent(escape(badstring));
}catch(e){
// If it isn't, an error will be thrown, and we can assume that we have an ISO string.
fixedstring=badstring;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…