需要在瀏覽器端實(shí)現(xiàn)對字符進(jìn)行GB2312,GBK,GB18030編碼解碼,搜索如何解決本問題時
搜索到iconv-lite,一個純JS字符編碼轉(zhuǎn)換工具。
文檔中表示在瀏覽器端可以通過browserify或者webpack使用。
安裝之后,在頁面import后,devServer編譯時報錯!
主要是以下兩種錯誤:
第一個 Can't resolve 'buffer'

對于這個錯誤,是因?yàn)樾枰蕾?code>buffer,但是項(xiàng)目中沒有。安裝buffer即可
npm install -D buffer
安裝之后再編譯,這個錯就沒有了
第二個 Cannot parse JSON: Unexpected token ";"

這個錯誤是因?yàn)橥ㄟ^
babel-loader解析iconv-lit中的json文件時出現(xiàn)了無法解析的錯誤。顯然,
json文件不應(yīng)該由babel-loader來解析檢查
webpack.config.js文件發(fā)現(xiàn)了如下配置
{
test: /\.jsx?/i,
use: ['babel-loader'],
},
由于此配置,使.json后綴文件匹配上了/\.jsx?/i正則,導(dǎo)致json文件被babel-loader解析,并報了錯。
改善一下正則即可。
改正為只有以.js或.jsx為結(jié)尾的文件,才使用babel-loader
{
test: /\.jsx?$/i,
use: ['babel-loader'],
},
改正之后再重新運(yùn)行run server

不報錯啦!(*^▽^*)
iconv-lite如何使用呢?
直接看文檔中的例子就可以了,可以將require方式改為import方式引入
import iconv from 'iconv-lite';
// Convert from an encoded buffer to a js string.
const str = iconv.decode(Buffer.from([0x68, 0x65, 0x6c, 0x6c, 0x6f]), 'GB2312');
// Convert from a js string to an encoded buffer.
const buf = iconv.encode("Sample input string", 'GB2312');
可以用啦(???)
另外,在知乎中看到這樣一篇文章,使用hack的方式獲取編碼
https://zhuanlan.zhihu.com/p/35537480
簡單測試了一下,一般的文字是可以得到正確編碼的,但是對于個別文字會得到意想不到的結(jié)果。
比如瞭,url中編碼后的結(jié)果是 %B2t 。這個t是什么鬼我實(shí)在是無法理解,而且,我改變accept-charset 為GBK 或者GB18030后,對于這個字的編碼都沒有改變。我懷疑這種方式無法區(qū)分這三種編碼,可能是因?yàn)檫@三種編碼是向下兼容的吧 ⊙(?◇?)?
因此,我覺得這個方式應(yīng)該是有點(diǎn)問題的。
這個hack方式的核心在于兩點(diǎn)
第一
form表單的accept-charset屬性,可以指定文本編碼方式。設(shè)置input的value后,通過get方式提交表單,可以在url中的參數(shù)部分(也就是?后面)得到編碼后的結(jié)果。
第二
由于form表單提交會刷新當(dāng)前頁面,所以創(chuàng)建一個隱藏的iframe,指定iframe的name屬性。然后設(shè)置form表單的target屬性與iframe的name一致。通過這種方式指定form提交到隱藏的iframe中,這樣刷新的就是iframe,而不是當(dāng)前頁面。
最后通過iframe.contentWindow.location.href獲取到iframe的url即可。
簡單記錄一下代碼:
html部分
<iframe style={{ display: 'none' }} id="hiddenFrame" name="encode" src="about:blank" />
<div style={{ display: 'none' }}>
<form method="get" acceptCharset="gb18030" target="encode">
<input id="hiddenInput" name="input" />
<input type="submit" value="submit" onClick={onSubmitClick} />
</form>
</div>
js部分
function getUrlGBCode(data: string) {
const form = document.getElementsByTagName('form')[0];
const iframe = document.getElementsByTagName('iframe')[0];
if (form) {
form.acceptCharset = 'gb2312';
const input = document.getElementById('hiddenInput') as HTMLInputElement;
input.value = data;
form.submit();
setTimeout(() => {
const url = iframe.contentWindow.location.href;
console.log('xixi', url);
}, 100);
}
}
2023-10-19