IE11富文本兼容------政务系统前端的深渊
背景:为什么还有 IE11
系统要求支持 IE11。
为什么不是 Chrome?
- 办公电脑全是 Windows 7 + IE11
- 单位统一采购,不能随便装浏览器
- 部分内部网站只支持 IE(ActiveX)
现状:Chrome 全球份额 70%+,但在政务系统里,IE11 还是主流。
问题1:富文本编辑器选择
富文本问题,有关于ie11的问题
使用2种方案,低于ie10使用fceditor,高于使用wangeditor
策略:根据浏览器版本加载不同的编辑器。
javascript
function getIEVersion() {
var ua = navigator.userAgent;
var msie = ua.indexOf('MSIE ');
if (msie > 0) {
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)));
}
var trident = ua.indexOf('Trident/');
if (trident > 0) {
var rv = ua.indexOf('rv:');
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)));
}
return -1;
}
var ieVersion = getIEVersion();
if (ieVersion >= 0 && ieVersion < 10) {
// IE9及以下:使用 fceditor(兼容性好但功能少)
loadEditor('fceditor');
} else {
// IE10+ 和其他浏览器:使用 wangeditor(功能多)
loadEditor('wangeditor');
}
问题:两套编辑器,两套维护成本。功能不一致,用户体验不统一。
问题2:富文本内容显示异常
乱码
富文本乱码问题解决
现象:IE11 下保存的富文本内容,在 Chrome 下显示乱码。
根因 :IE11 的富文本编辑器用 gbk 编码,Chrome 用 utf-8。
解决:统一使用 UTF-8。
html
<meta charset="UTF-8">
<!-- 或者 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
内容丢失
富文本值的问题
富文本问题处理
现象:IE11 下编辑的富文本,保存后部分内容丢失(如图片、表格)。
根因 :IE11 的 innerHTML 返回的 HTML 结构和其他浏览器不同。
javascript
// IE11 下 innerHTML 的问题
// Chrome: <p>文本</p>
// IE11: <P>文本</P>(标签大写)
// Chrome: <img src="..." alt="">
// IE11: <IMG src="..." alt="">(标签大写)
// 同时 IE11 可能会添加多余的 style 属性
解决:保存前做 HTML 标准化。
javascript
function normalizeHTML(html) {
html = html.replace(/<(\/?)(\w+)/g, function(match, slash, tag) {
return '<' + slash + tag.toLowerCase();
});
html = html.replace(/style="[^"]*"/gi, function(style) {
var keepStyles = ['font-size', 'font-weight', 'color', 'text-align'];
var styles = style.replace(/style="/i, '').replace(/"$/, '').split(';');
var filtered = styles.filter(function(s) {
return keepStyles.some(function(ks) {
return s.trim().indexOf(ks) === 0;
});
});
return filtered.length > 0 ? 'style="' + filtered.join(';') + '"' : '';
});
return html;
}
问题3:富文本工具栏控制
内控系统(富文本控制,默认打开菜单栏)
richedit只读控制
需求:根据用户权限,控制富文本编辑器的功能。
javascript
var editorConfig = {
toolbar: []
};
if (userRole === 'admin') {
editorConfig.toolbar = [
'source', '|',
'bold', 'italic', 'underline', 'strikethrough', '|',
'forecolor', 'backcolor', '|',
'insertimage', 'inserttable', '|',
'fontsize', 'fontfamily'
];
} else if (userRole === 'editor') {
editorConfig.toolbar = [
'bold', 'italic', 'underline', '|',
'insertimage'
];
} else {
editorConfig.toolbar = [];
editorConfig.readonly = true;
}
IE11 问题:只读模式下,IE11 仍然可以编辑内容。
解决:
javascript
function setReadonly(editor, readonly) {
if (readonly) {
editor.disable();
if (getIEVersion() > 0) {
var body = editor.$editor.find('.w-e-text');
body.attr('contenteditable', 'false');
}
} else {
editor.enable();
if (getIEVersion() > 0) {
var body = editor.$editor.find('.w-e-text');
body.attr('contenteditable', 'true');
}
}
}
问题4:文件上传兼容
富文本文件上传问题处理
场景:在富文本编辑器中上传图片。
IE11 问题 :FormData 和 XMLHttpRequest 在 IE11 下表现不同。
javascript
function uploadImage(file, callback) {
var formData = new FormData();
formData.append('file', file);
var xhr = new XMLHttpRequest();
if (xhr.upload) {
xhr.upload.onprogress = function(e) {
// 进度条(IE11 不支持)
};
}
xhr.onload = function() {
var result;
try {
result = JSON.parse(xhr.responseText);
} catch (e) {
result = { url: xhr.responseText };
}
callback(result);
};
xhr.open('POST', '/upload/image');
xhr.send(formData);
}
问题5:IE11 下 a 标签问题
ie11下<a>标签问题解决 信任站点添加:about:blank
现象:IE11 下点击链接没反应。
根因 :IE11 的安全策略,<a href="javascript:void(0)"> 被拦截。
解决:
html
<!-- 改为 -->
<a href="javascript:;" onclick="handleClick()">链接</a>
<!-- 或 -->
<a href="#" onclick="handleClick(); return false;">链接</a>
<!-- 信任站点设置 -->
<!-- 把系统域名添加到 IE 的信任站点 -->
问题6:JSON 对象兼容
海口海关兼容模式问题处理(JSON对象,低版本ie没有)
现象 :IE11(兼容模式)下报 JSON is not defined。
根因 :IE8 以下没有原生的 JSON 对象。
解决:
html
<!-- 引入 json2.js 兼容库 -->
<!--[if lt IE 10]>
<script src="/static/js/json2.js"></script>
<![endif]-->
问题7:负载均衡下 Session 丢失
一体化ie浏览器经过负载查询失败问题分析
现象:IE 经过负载均衡后,查询请求失败。
根因:IE 的 Cookie 处理机制导致 Session 无法保持。
解决:
apache
<Proxy balancer://mycluster>
BalancerMember http://10.12.30.100:8080 route=node1
BalancerMember http://10.12.30.101:8080 route=node2
ProxySet stickysession=JSESSIONID
</Proxy>
兼容方案总结
1. 前端框架选择
yaml
recommendation:
framework: "jQuery 3.x"
ui: "Bootstrap 3.x"
editor: "wangEditor(IE11 兼容版)"
polyfill: "html5shiv + respond.js + json2.js"
2. HTML 模板
html
<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<!--[if lt IE 9]>
<script src="/static/js/html5shiv.min.js"></script>
<script src="/static/js/respond.min.js"></script>
<![endif]-->
<!--[if lt IE 10]>
<script src="/static/js/json2.js"></script>
<![endif]-->
</head>
3. CSS 兼容
css
/* IE11 兼容 */
_:-ms-fullscreen, :root .ie11-hack {
/* 仅 IE11 生效 */
}
/* 透明背景 */
background-color: rgba(0, 0, 0, 0.5);
/* IE 用滤镜代替 */
filter: progid:DXImageTransform.Microsoft.gradient(
startColorstr=#80000000, endColorstr=#80000000
);
经验教训
1. IE11 不是浏览器,是历史遗留问题
每次版本迭代都要考虑 IE11,相当于背着 10 年前的包袱开发。
建议:能放弃就放弃,不能放弃就降级(IE11 用户用简化版)。
2. 两套方案比一套方案更痛苦
低于ie10使用fceditor,高于使用wangeditor
两套编辑器,意味着两套 bug、两套维护。能用一套就别用两套。
3. 兼容性测试不能省
每次发布前,至少在 IE11、Chrome、Edge 三个浏览器上跑一遍核心功能。
4. 政务系统的特殊性
- 不是不想升级,是升级成本太高
- 不是不想换 Chrome,是 IT 策略不允许
- 不是不想用新技术,是旧系统不兼容
理解业务场景,比吐槽技术落后更有用。