欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue兼容ie9的問題全面解決方案

 更新時(shí)間:2018年06月19日 15:03:07   作者:TerryZ  
這篇文章主要介紹了Vue兼容ie9的問題全面解決方案,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

前言

背景情況

  1. vue - 2.5.11
  2. vue-cli 使用模板 webpack-simple
  3. http請求:axios

Vue 官方對于 ie 瀏覽器版本兼容情況的描述是 ie9+,即是 ie9 及更高的版本。經(jīng)過測試,Vue 的核心框架 vuejs 本身,以及生態(tài)的官方核心插件(VueRouter、Vuex等)均可以在 ie9 上正常使用。

Vue 的作者尤雨溪對于Vue 的學(xué)習(xí)建議 中有提及為了將項(xiàng)目更好的生態(tài)化/工程化,要盡可能學(xué)習(xí)及使用新的 ECMAScript 規(guī)范。目前 ES6/ES2015 是可用度和穩(wěn)定度較高的規(guī)范,文檔齊全,國內(nèi)還有 阮一峰 《ECMAScript 6 入門》 做了大量的文檔翻譯,開發(fā)環(huán)境可謂完善。然而版本較舊的瀏覽器并不支持 es6 規(guī)范,尤其是 ie 瀏覽器,即使是最高的 ie11 版本,對于 es6 規(guī)范也支持得并不全。如此則需要對所有原生不支持 ES6 特性的瀏覽器做兼容性處理。

本文將針對使用 Vue 生態(tài)開發(fā)完成的網(wǎng)站,以 ie9 版本為基礎(chǔ)兼容目標(biāo),實(shí)現(xiàn)全功能正常使用的全面兼容解決方案。

ES6兼容

在 ie9 的環(huán)境上,es6 的部分新對象、表達(dá)式,并不支持,解決方案是使用 babel-polyfill 組件,它可以將 es6 的代碼翻譯成低版本瀏覽器可以識別的 es5 代碼

npm i babel-polyfill --save-dev

安裝完成后,在項(xiàng)目的主入口文件 main.js 的首行就可以直接引用

import 'babel-polyfill';

在項(xiàng)目使用 vue-cli 生成的代碼中,根目錄有一個(gè) .babelrc 文件,這是項(xiàng)目使用 babel 的配置文件。在默認(rèn)生成的模板內(nèi)容中,增加 "useBuiltIns": "entry" 的設(shè)置內(nèi)容,這是一個(gè)指定哪些內(nèi)容需要被 polyfill(兼容) 的設(shè)置

useBuiltIns 有三個(gè)設(shè)置選項(xiàng)

  1. false - 不做任何操作
  2. entry - 根據(jù)瀏覽器版本的支持,將 polyfill 需求拆分引入,僅引入有瀏覽器不支持的polyfill
  3. usage - 檢測代碼中 ES6/7/8 等的使用情況,僅僅加載代碼中用到的 polyfill

這里推薦設(shè)置為 entry ,完整的 .babelrc 內(nèi)容如下:

{
 "presets": [
 [
  "env",
  {
  "modules": false,
  "useBuiltIns": "entry"
  }
 ],
 "stage-3"
 ]
}

加入這些代碼后,工程里的大部分內(nèi)容已可兼容到 ie9 版本

Number對象

即使在使用 babel-polyfill 做代碼翻譯后,發(fā)現(xiàn)還是有一些 es6 的新特性并沒有解決,比如說 Number 對象的 parseIntparseFloat 方法

es6 將全局方法 parseInt() parseFloat() ,移植到 Number 對象上面,行為完全保持不變。這樣做的目的,是逐步減少全局性方法,使得語言逐步模塊化。

解決這個(gè)問題不需要引入包來解決,同樣在項(xiàng)目主入口文件 main.js 加入以下代碼(代碼盡可能靠前,最好是在引用 babel-polyfill 之后 )

if (Number.parseInt === undefined) Number.parseInt = window.parseInt;
if (Number.parseFloat === undefined) Number.parseFloat = window.parseFloat;

requestAnimationFrame方法

window.requestAnimationFrame 是瀏覽器用于定時(shí)循環(huán)操作的一個(gè)接口,類似于 setTimeout,主要用途是按幀對網(wǎng)頁進(jìn)行重繪。

requestAnimationFrame 的優(yōu)勢,在于充分利用顯示器的刷新機(jī)制,比較節(jié)省系統(tǒng)資源。顯示器有固定的刷新頻率(60Hz或75Hz),也就是說,每秒最多只能重繪60次或75次,requestAnimationFrame 的基本思想就是與這個(gè)刷新頻率保持同步,利用這個(gè)刷新頻率進(jìn)行頁面重繪。此外,使用這個(gè)API,一旦頁面不處于瀏覽器的當(dāng)前標(biāo)簽,就會自動停止刷新。這就節(jié)省了CPU、GPU和電力。

不過有一點(diǎn)需要注意,requestAnimationFrame 是在主線程上完成。這意味著,如果主線程非常繁忙,requestAnimationFrame 的動畫效果會大打折扣。

window.requestAnimationFrame() 方法告訴瀏覽器您希望執(zhí)行動畫并請求瀏覽器在下一次重繪之前調(diào)用指定的函數(shù)來更新動畫。該方法使用一個(gè)回調(diào)函數(shù)作為參數(shù),這個(gè)回調(diào)函數(shù)會在瀏覽器重繪之前調(diào)用。

有部分第三方組件就使用了這個(gè)方法,例如部分文件上傳、圖片處理類的組件;那么在這類型的組件在 ie9 下使用時(shí),會報(bào)出

SCRIPT5007: Expected object.

window.requestAnimationFrame() 的最低兼容 ie 版本為 10,那么在 ie9 上做兼容就需要制作 requestAnimationFrame polyfill

(function() {
  var lastTime = 0;
  var vendors = ['ms', 'moz', 'webkit', 'o'];
  for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
    window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 
                  || window[vendors[x]+'CancelRequestAnimationFrame'];
  }
 
  if (!window.requestAnimationFrame)
    window.requestAnimationFrame = function(callback, element) {
      var currTime = new Date().getTime();
      var timeToCall = Math.max(0, 16 - (currTime - lastTime));
      var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
       timeToCall);
      lastTime = currTime + timeToCall;
      return id;
    };
 
  if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame = function(id) {
      clearTimeout(id);
    };
}());

Gist:requestAnimationFrame polyfill

這部分代碼同樣是盡可能在網(wǎng)站入口處就執(zhí)行

http網(wǎng)絡(luò)請求(跨域)

在大多數(shù)的 Web 項(xiàng)目中(以 JavaWeb 為例),網(wǎng)站的頁面和服務(wù)(至少是 controller 層)在同一個(gè)工程進(jìn)行開發(fā)和部署,在大前端的新型模式下,我們建議盡可能對網(wǎng)站的前端和后端進(jìn)行完全分離,前后端分離的好處和意義這里不再贅述。

既然是前后端分離,那么部署也必然是各自獨(dú)立部署,不同的訪問路徑,就會產(chǎn)生跨域訪問的問題(同一站點(diǎn),不同端口號也是跨域)

在此設(shè)定背景情況:

  1. 服務(wù)端已完整開啟 CROS 跨域支持
  2. http 組件使用 axios
  3. axios 設(shè)置 withCredentials 為 true 開啟跨域訪問時(shí)攜帶 cookie 數(shù)據(jù)

高版本瀏覽器(ie10+ 或 chrome, ff)僅需要完成背景情況中的功能,即可支持跨域數(shù)據(jù)請求功能

axios 進(jìn)行數(shù)據(jù)請求時(shí),默認(rèn)使用 XMLHttpRequest 對象,在檢測到當(dāng)前請求是跨域訪問時(shí),axios 會測試瀏覽器是否支持 XDomainRequest 對象,若支持則優(yōu)先使用。

ie8 / ie9 的 XMLHttpRequest 對象,不支持跨域訪問,該對象在 ie10 后才原生支持跨域訪問。微軟的解決方案是在 ie8 / ie9 中提供了XDomainRequest(XDR) 對象來進(jìn)行解決跨域問題,雖然使用該對象可以跨域訪問成功,并返回?cái)?shù)據(jù),但它卻依然是一個(gè)功能不完整的半成品,它的使用有諸多限制:

  1. XDR 僅支持 GET 與 POST 兩種請求方式
  2. XDR 不支持自定義的請求頭,若服務(wù)端使用 header 的自定義參數(shù)進(jìn)行做身份驗(yàn)證,則不可用
  3. 請求頭的 Content-Type 只允許設(shè)置為 text/plain
  4. XDR 不允許跨協(xié)議的請求,如果網(wǎng)頁在 HTTP 協(xié)議下,就只能請求 HTTP 協(xié)議下的接口,不能訪問 HTTPS 接口
  5. XDR 只接受HTTP/HTTPS 的請求
  6. 發(fā)起請求的時(shí)候,不會攜帶 authentication 或 cookies

微軟雖然提供了解決方案,但卻是不折不扣的雞肋,根本無法勝任系統(tǒng)中各種場景的數(shù)據(jù)請求需求,至此,axios 對 ie9 的跨域數(shù)據(jù)請求已無能為力。

完美解決方案:代理(proxy)

雖然 axios 對 ie9 跨域已無能為力,但前端項(xiàng)目打包的解決方案 webpack 提供了一個(gè)優(yōu)雅而徹底解決問題的方式:代理

devServer.proxy

webpack 的 devServer.proxy 的功能是由http-proxy-middleware 項(xiàng)目來實(shí)現(xiàn)的

實(shí)現(xiàn)原理是將目標(biāo)位置的請求代理為前端服務(wù)本地的請求,既然是代理成為本地的請求,就不存在跨域的問題,axios 就會用回 XMLHttpRequest 對象進(jìn)行數(shù)據(jù)請求,一切都恢復(fù)正常了,header、cookies、content-type、authentication 等內(nèi)容都被正確傳遞到服務(wù)端。

項(xiàng)目中 webpack.config.js 的配置

devServer: {
  historyApiFallback: true,
  noInfo: true,
  overlay: true,
  proxy: {
    '/api': {
      target: 'http://localhost:8081/myserver',
      pathRewrite: {
        '^/api': ''
      }
    }
  }
}

配置中指定了將 http://localhost:8081/myserver 服務(wù)的位置代理為本地前端服務(wù)的 http://localhost:8080/api。例如需要讀取用戶信息的原請求是 http://localhost:8081/myserver/user/zhangsan,代理后,就變?yōu)?http://localhost:8080/api/user/zhangsan。

即是 /api 的前綴代表了服務(wù)端,所以在使用 axios 時(shí),需要對每個(gè)服務(wù)端請求都增加上 /api 的前綴;通常在項(xiàng)目開發(fā)中,需要對數(shù)據(jù)請求組件 axios 進(jìn)行二次封裝,以達(dá)到統(tǒng)一設(shè)置默認(rèn)參數(shù),統(tǒng)一數(shù)據(jù)請求入口等目的,那么此時(shí)就只需要在二次封裝的文件里統(tǒng)一調(diào)整請求前綴即可。

不過,webpack 的 devServer.proxy 僅在開發(fā)模式下可用,生產(chǎn)模式下無法使用。開發(fā)模式下,調(diào)試服務(wù)可以讀取 webpack.config.js 中的配置內(nèi)容進(jìn)行實(shí)時(shí)代理,而項(xiàng)目在部署到生產(chǎn)環(huán)境前,需要將工程進(jìn)行編譯轉(zhuǎn)換成靜態(tài)的 js 文件,沒有調(diào)試服務(wù)的支撐自然是無法進(jìn)行請求代理的。

nginx 配置

雖然 devServer.proxy 的功能僅能工作于開發(fā)模式,那么在生產(chǎn)模式下,自然也是有解決方案的;通常 Vue 的項(xiàng)目在編譯成最終的 js 文件后,僅需要靜態(tài)服務(wù)器即可,這其中又以 nginx 為最優(yōu)選擇方案,輕量、高性能、高并發(fā)、反向代理服務(wù)等均為其優(yōu)點(diǎn),這里需要做的數(shù)據(jù)請求代理的功能就使用到了 nginx 的 反向代理 功能

conf/nginx.conf 文件配置增加以下內(nèi)容

location /api/ {
  proxy_pass http://localhost:8081/myserver/;
}

該配置同樣是將 http://localhost:8081/myserver/ 的目標(biāo)服務(wù)端位置代理為本地服務(wù)的 /api 路徑,如此,生產(chǎn)環(huán)境下的數(shù)據(jù)請求問題也得以解決

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • React和Vue實(shí)現(xiàn)路由懶加載的示例代碼

    React和Vue實(shí)現(xiàn)路由懶加載的示例代碼

    路由懶加載是一項(xiàng)關(guān)鍵技術(shù),它可以幫助我們提高Web應(yīng)用的加載速度,本文主要介紹了React和Vue實(shí)現(xiàn)路由懶加載的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • element中el-table表頭通過header-row-style設(shè)置樣式

    element中el-table表頭通過header-row-style設(shè)置樣式

    有些時(shí)候需要給element-ui表頭設(shè)置不同樣式,本文主要介紹了element中el-table表頭通過header-row-style設(shè)置樣式,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • 詳解在Vue.js編寫更好的v-for循環(huán)的6種技巧

    詳解在Vue.js編寫更好的v-for循環(huán)的6種技巧

    這篇文章主要介紹了詳解在Vue.js編寫更好的v-for循環(huán)的6種技巧,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • vue3+高德地圖只展示指定市、區(qū)行政區(qū)域的地圖以及遮罩反向鏤空其他地區(qū)

    vue3+高德地圖只展示指定市、區(qū)行政區(qū)域的地圖以及遮罩反向鏤空其他地區(qū)

    vue大屏項(xiàng)目開發(fā),客戶覺得地圖上的文字標(biāo)注太多了,要求地圖上只顯示省市等主要城市的標(biāo)注,這篇文章主要給大家介紹了關(guān)于vue3+高德地圖只展示指定市、區(qū)行政區(qū)域的地圖以及遮罩反向鏤空其他地區(qū)的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • vue3基于script?setup語法$refs的使用

    vue3基于script?setup語法$refs的使用

    這篇文章主要介紹了vue3基于script?setup語法$refs的使用,<BR>?在用vue3開發(fā)項(xiàng)目的時(shí)候,需要調(diào)用子組件的方法,于是想著用$refs來實(shí)現(xiàn),但是我是使用script?setup語法糖,原先vue2的語法已經(jīng)不適用了。下面我們一起進(jìn)入文章看詳細(xì)內(nèi)容吧</P><P>
    2021-12-12
  • 在vue中使用jointjs的方法

    在vue中使用jointjs的方法

    本篇文章主要介紹了在vue中使用jointjs的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-03-03
  • vue下history模式刷新后404錯(cuò)誤解決方法

    vue下history模式刷新后404錯(cuò)誤解決方法

    這篇文章主要介紹了vue下history模式刷新后404錯(cuò)誤解決方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • Vue3?源碼分析reactive?readonly實(shí)例

    Vue3?源碼分析reactive?readonly實(shí)例

    這篇文章主要為大家介紹了Vue3?源碼分析reactive?readonly實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • VueJS 集成 Medium Editor的示例代碼 (自定義編輯器按鈕)

    VueJS 集成 Medium Editor的示例代碼 (自定義編輯器按鈕)

    本篇文章主要介紹了VueJS 集成 Medium Editor的示例代碼 (自定義編輯器按鈕),具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-08-08
  • elementui中tabel組件的scope.$index的使用及說明

    elementui中tabel組件的scope.$index的使用及說明

    這篇文章主要介紹了elementui中tabel組件的scope.$index的使用及說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10

最新評論