您现在的位置是:网站首页 > 数据安全考虑文章详情
数据安全考虑
陈川
【
ECharts
】
65440人已围观
3483字
数据安全考虑
ECharts作为一款开源可视化库,数据安全是其核心设计原则之一。开发者需要关注数据传输、存储、渲染全流程的安全防护,避免敏感信息泄露或被篡改。以下从多个维度分析ECharts使用中的数据安全实践。
数据传输安全
使用HTTPS协议加载ECharts资源是基础要求。通过CDN引入时务必检查URL是否为https://
开头:
// 安全示例
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
// 不安全示例(避免使用)
<script src="http://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
异步数据请求必须启用CORS安全策略。建议在axios实例中全局配置:
const instance = axios.create({
baseURL: 'https://api.example.com',
withCredentials: true,
headers: { 'X-Requested-With': 'XMLHttpRequest' }
});
数据脱敏处理
展示敏感数据时应进行前端脱敏。例如身份证号展示可采用正则替换:
function desensitizeIdCard(id) {
return id.replace(/(\d{4})\d{10}(\w{4})/, '$1**********$2');
}
// 在ECharts配置项中应用
option.series[0].data.forEach(item => {
item.value = desensitizeIdCard(item.value);
});
金融类数据建议采用精度控制:
function formatCurrency(value) {
return (value / 10000).toFixed(2) + '万';
}
防XSS注入
ECharts默认会对HTML内容进行转义,但自定义富文本时需要手动防护:
import DOMPurify from 'dompurify';
option.tooltip.formatter = params => {
const safeName = DOMPurify.sanitize(params.name);
return `${safeName}: ${params.value}`;
};
避免直接使用未处理的用户输入作为配置项:
// 危险示例(绝对避免)
option.title.text = userInputText;
// 安全做法
option.title.text = xssFilters.inHTMLData(userInputText);
本地存储安全
使用localStorage缓存图表配置时需加密:
import CryptoJS from 'crypto-js';
const SECRET_KEY = 'your-32-byte-key';
function saveConfig(config) {
const encrypted = CryptoJS.AES.encrypt(
JSON.stringify(config),
SECRET_KEY
).toString();
localStorage.setItem('chartConfig', encrypted);
}
水印与版权保护
防止截图泄露可通过动态水印增强:
function addWatermark(chartDom) {
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 100;
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgba(0,0,0,0.1)';
ctx.font = '16px Arial';
ctx.rotate(-20 * Math.PI / 180);
ctx.fillText('Confidential', 50, 70);
chartDom.style.backgroundImage = `url(${canvas.toDataURL()})`;
}
权限控制
基于RBAC实现图表元素级权限:
const userRoles = ['viewer', 'editor'];
const chartConfig = {
toolbox: {
show: userRoles.includes('editor'),
feature: {
saveAsImage: userRoles.includes('admin')
}
}
};
性能与安全平衡
大数据量下采用分片加载策略:
async function loadLargeData(chartInstance, url) {
const CHUNK_SIZE = 50000;
let offset = 0;
while (true) {
const res = await fetch(`${url}?offset=${offset}&limit=${CHUNK_SIZE}`);
const data = await res.json();
if (data.length === 0) break;
chartInstance.appendData({
seriesIndex: 0,
data: data
});
offset += CHUNK_SIZE;
}
}
日志与监控
集成Sentry监控图表异常:
import * as Sentry from '@sentry/browser';
try {
myChart.setOption(complexOption);
} catch (error) {
Sentry.captureException(error, {
tags: { chartType: 'heatmap' }
});
}
服务端渲染安全
Node端渲染时限制内存使用:
const echarts = require('echarts/node/echarts');
echarts.setPlatformAPI({
createCanvas() {
return require('canvas').createCanvas(800, 600);
},
measureText(text, font) {
// 实现文本测量逻辑
}
});
// 限制渲染时间
const renderPromise = chart.renderToCanvas();
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error('Timeout')), 5000);
});
await Promise.race([renderPromise, timeoutPromise]);