Node.js将ISO8859-1编码为UTF-8
我有一个应用程序,允许用户坚持string到数据库,这些string可能包含表情符号。 我遇到的问题是一个表情符号,例如😊
将被存储在MySQL中作为😊
当我使用PHP MySQL客户端检索这个string并将其呈现在Web浏览器中时,它可能会因为Content-Type
设置为UTF-8而呈现罚款。 当我尝试读取node.js中的string时,我找回了我认为是ISO8859-1编码的字😊
。 桌上的字符集设置为latin1
,这就是我从中获取ISO8859-1的地方。
在node.js中对string进行编码的正确方法是什么,以便我可以看到表情符号而不是由MySQL设置的编码。
😊
是😊
为😊
。 将前者解释为latin1,您将得到hexF09F988A
,即表情符号的UTF-8
hex。
(注意:MySQL以外的UTF-8
相当于MySQL内部的utf8mb4
。)
在MySQL中,必须使用CHARACTER SET utf8mb4
声明列/表。 你还必须声明存储/读取的数据是utf8mb4
编码的。 注意: utf8
不够的。
做一个SELECT HEX(col) FROM ...
看看你是否得到那个表情符号的hex。 如果是这种情况, 并且该列当前是latin1
,那么修复的一部分就是仔细将该列转换为utf8mb4。 也就是说,你有CHARACTER SET latin1
,但是有UTF-8字节; 这将固定字符集时留下字节。 假设列已经是VARCHAR(111) CHARACTER SET latin1 NOT NULL
,那么执行这2步ALTER:
ALTER TABLE tbl MODIFY COLUMN col VARBINARY(111) NOT NULL; ALTER TABLE tbl MODIFY COLUMN col VARCHAR(111) CHARACTER SET utf8mb4 NOT NULL;
其他任何转换机制几乎都会变得糟糕。
至于build立正确的连接,它是这样的node.js:
var connection = mysql.createConnection({ ... , charset : 'utf8mb4'});
你不需要,也不应该转换编码。 只要使用正确的协议。 如果以UTF-8发送HTML页面,浏览器将以UTF-8格式将数据发送回服务器。
然后你想把数据存储到你的数据库,这是latin1
,根本不工作。 您必须将数据库转换为UTF-8。 这包括数据库,表格,最后是列本身。 还要确保你的数据库客户端被configuration为以UTF-8连接,因为客户端本身必须声明它的编码。
一旦你获得了UTF-8的全部数据stream,一切都将毫无问题地工作。
服务器 – > GET HTML – > POST – >服务器 – > SQL客户端 – >数据库 – >表 – >列
我发现了一个超级肮脏的方式将其转换回来:
const isoToUtfTable = { 'ð': 0xf0, 'Ÿ': 0x9f, '˜': 0x98, 'Š': 0x8a }; function convertISO8859ToUtf8(s) { const buf = new Uint8Array([...s].map(c => isoToUtfTable[c])); return String.fromCharCode(...buf) } function decode_utf8(s) { return decodeURIComponent(escape(s)); } console.log(decode_utf8(convertISO8859ToUtf8('😊')))
build议使用iconv
(简单的ISO-8859-1到UTF-8的转换)
从这个要点
var iconv = require('iconv'); function toUTF8(body) { // convert from iso-8859-1 to utf-8 var ic = new iconv.Iconv('iso-8859-1', 'utf-8'); var buf = ic.convert(body); return buf.toString('utf-8'); }
这里如果你通过了ISO-8859-1中的任何东西,它会返回UTF-8。
例如,
toUTF8("😊");
将返回😊
也许试着看看node-iconv 。
const iconv = new Iconv('ISO-8859-2', 'UTF-8'); const buffer = iconv.convert(something); console.log(buffer); console.log(buffer.toString('UTF8'));