Highcharts 官方提供的导出服务器(https://export.highcharts.com.cn) 默认只支持 UTF-8 编码,如果从 GBK 页面提交导出请求,导出的结果是包含乱码的图片,这是很常见的编码问题。
在不能改变页面编码的情况下,解决办法有两种:
- 修改导出服务器源码(源码可以到 node-export-server 下载,详见 教程)使其能够支持 GBK 编码
- 另外一种方法是将发送到导出服务器的数据改成 UTF-8。
第一种方法相对比较麻烦,这里我们就简单说说第二种方法的具体实现方法。
主流浏览器
对于主流浏览器( IE8 以上),我们可以在 exporting.formAttributes
中加入编码属性即可,代码是:
exporting: {
url: 'https://export.highcharts.com.cn',
formAttributes: {
// 在导出的 formAttributes 中设置表单的编码
"acceptCharset": "UTF-8"
}
}
formAttributes 的作用是指定在调用 Highcharts.post
函数时创建的表单的额外属性,上面的代码其实就相当于
<form accept-charset="UTF-8">
至于 Highcharts.post 为什么会创建表单,可以自行阅读源码。
IE
对于 低版本 IE 来说(IE8 以下),他完全不认 form 的 accept-charset
属性,他提交表单的编码是按照页面的 meta 指定的字符集。
可喜的是 IE 浏览器中的 document.charset
是可读可写的,并且在改变它时页面是不会用新的编码重新渲染页面。
结合 Highcharts,我们可以在 Highcharts.post
中做处理,即在提交数据之前将页面的编码设置为 UTF-8,并在导出结束后恢复原始编码,具体的实现代码如下:
H.post = function(url, data, formAttributes) {
var name,
form;
if (!formAttributes) {
formAttributes = {}
}
// 增加表单属性
formAttributes.acceptCharset = "UTF-8";
form = createElement('form', merge({
method: 'post',
action: url,
enctype: 'multipart/form-data'
}, formAttributes), {
display: 'none'
}, document.body);
for (name in data) {
createElement('input', {
type: 'hidden',
name: name,
value: data[name]
}, null, form);
}
// 1. 修改网页编码
document.charset = 'UTF-8';
form.submit();
// clean up
discardElement(form);
// 2. 恢复原始编码
document.charset = originCharset;
}
最后,我们将上述两个解决方法整合在一起,并编写成一个 Highcharts 插件,插件代码如下:
(function(H) {
var DEFAULT_VERSION = "8.0",
ua = navigator.userAgent.toLowerCase(),
isIE = ua.indexOf("msie") > -1,
safariVersion;
if (isIE) {
safariVersion = ua.match(/msie ([\d.]+)/)[1];
}
if (safariVersion <= DEFAULT_VERSION) {
var discardElement = H.discardElement,
createElement = H.createElement,
merge = H.merge,
// 保存页面的原始编码
originCharset = document.charset;
H.post = function(url, data, formAttributes) {
var name,
form;
if (!formAttributes) {
formAttributes = {}
}
// 增加表单属性
formAttributes.acceptCharset = "UTF-8";
form = createElement('form', merge({
method: 'post',
action: url,
enctype: 'multipart/form-data'
}, formAttributes), {
display: 'none'
}, document.body);
for (name in data) {
createElement('input', {
type: 'hidden',
name: name,
value: data[name]
}, null, form);
}
// 1. 修改网页编码
document.charset = 'UTF-8';
form.submit();
// clean up
discardElement(form);
// 2. 恢复原始编码
document.charset = originCharset;
}
}
}(Highcharts));
插件的使用方法很简单,只需要在 highcharts.js 之后引入插件文件即可。