最近專案進入到了第三方整合的環節,整合第三方監控非要用IE,咋辦?老闆讓我將後臺管理系統的框架相容下IE,一直都是在chrome下開發的,也不知道IE下是什麼鬼。
目前後臺管理系統前端搭建方式
目前系統是用vue-cli@2.0生成的,UI框架使用的是iview,ajax請求使用的是axois,此外就沒有什麼特殊的npm包了。
需要解決的相容問題
經過自己的一番測試,目前主要有以下的相容問題:
- 在IE下由於沒有promise,所以axios不能用了;
- 在涉及到flex、fixed、absolute定位時,IE瀏覽器下的顯示效果有較大的區別;
- excel表單匯出異常;
- 部分使用的npm包中的程式碼未經編譯會有一些ES6的語法;
- vue-router路由失效;
- IE自動快取ajax請求結果。
如何解決這些問題
- 解決第一個問題需要在專案中引入babel-polyfill, 我的處理方式時在build->webpack.base.config.js檔案中的新增一下的配置:
- 解決第二個問題則需要自己寫一些相容性比較好的樣式,在這裡我就不做過多的解釋了;
- 第三個問題的解決過程比較的曲折,系統的下載是同過介面返回檔案流的形式進行下載的,可以看下我原來的程式碼,原先通過axios的攔截器來獲取響應內容的格式,然後進行下載,但是在IE的相容測試過程中發現了一個問題,那就是axios在chrome和IE下的表現不一致,具體哪裡一致可以簡單的說下:
const downloadUrl = url => {
let iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = url;
iframe.onload = function () {
document.body.removeChild(iframe);
};
document.body.appendChild(iframe);
};
// 攔截二進位制響應流
if (res.headers && (res.headers['content-type'] === 'application/vnd.ms-excel;charset=UTF-8' || res.headers['content-type'] === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || res.headers['content-type'] === 'application/octet-stream;charset=UTF-8')) {
downloadUrl(res.request.responseURL);
return
}
複製程式碼
這裡面的問題在於在IE瀏覽器中res.request.responseURL這個屬性是不存在的,就算存在了,在進行檔案下載時也會出現異常,後臺看到很多人都出現了這樣的問題,怎麼辦,我相信這個問題一定是可以解決的,雖然沒有搜到合適的方案,但是一個網友提示這一切的問題都是使用了第三方封裝的ajax請求,那為什麼不自己手寫一個原生的ajax請求呢?切換思路後發現,果然是可以的,ajax下載檔案流可以使用以下程式碼:
utils.exportFiles = (type = 'GET', url = null) => {
var xhr = null
if (window.XMLHttpRequest) { // Mozilla 瀏覽器
xhr = new XMLHttpRequest()
} else {
if (window.ActiveXObject) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP')
} catch (e) {
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP')
} catch (e) {
}
}
}
}
xhr.open(type, url, true)
xhr.responseType = 'blob'
if (type === 'POST') {
xhr.setRequestHeader('Content-type', 'application/json')
}
xhr.onload = function (res) {
var contentDisposition = xhr.getResponseHeader('content-disposition')
var contentType = xhr.getResponseHeader('content-type')
var filename = contentDisposition.split(';')[2]
// eslint-disable-next-line no-eval
eval(filename)
filename = decodeURI(filename)
if (this.status === 201) {
var blob = this.response
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE 瀏覽器進行下載
window.navigator.msSaveBlob(blob, filename)
} else {
// 非瀏覽器進行下載
var downloadUrl = document.createElement('a')
downloadUrl.download = filename
downloadUrl.style.display = 'none'
downloadUrl.href = URL.createObjectURL(blob)
document.body.appendChild(downloadUrl)
downloadUrl.click()
URL.revokeObjectURL(downloadUrl.href)
document.body.removeChild(downloadUrl)
}
} else {
console.log('匯出錯誤')
}
}
xhr.send()
}
複製程式碼
第四個問題同樣還是一些webpack打包的問題,在vue-cli2.0生成的專案中,哪些js會使用babel-loader是這樣配置的:
我們可以看到,其針對3個檔案加的js程式碼使用babel-loader,將需要使用babel-loader的npm包新增到其中即可。 第五個問題百度可以搜到,其中我比較推薦的解決方案如下:const IE11RouterFix = {
methods: {
hashChangeHandler: function () {
this.$router.push(window.location.hash.substring(1, window.location.hash.length));
},
isIE11: function () { return !!window.MSInputMethodContext && !!document.documentMode; }
},
mounted: function () { if (this.isIE11()) { window.addEventListener('hashchange', this.hashChangeHandler); } },
destroyed: function () { if (this.isIE11()) { window.removeEventListener('hashchange', this.hashChangeHandler); } }
}
export default IE11RouterFix
var vm = new Vue({
el: '#app',
router,
store,
mixins: [IE11RouterFix],
components: {
App,
},
template: '<App/>'
});
複製程式碼
第6個問題是過了一段時候發現的,IE會自動的快取請求的結果,那麼對系統中的一些操作是有影響的,比如說是在資料儲存完成之後回到列表頁的重新整理,取到的資料是快取中的資料。怎麼辦,我們可以在axios的請求攔截器中自動為請求地址新增時間戳,保證每次的請求的地址是不一樣的。
總結
以上耗時一天的IE相容就完成了,目前只能相容到IE11,IE10,其他的我已經放棄了,就算再相容完成後,系統再IE10下的表現也不是特別的好,感覺比較卡,再IE11下也只能說是正常。