vue在开发环境怎么兼容ie_Vue兼容ie9的问题全⾯解决⽅案_
⽓质_前端开发者
前⾔
背景情况
http请求:axios
Vue 官⽅对于 ie 浏览器版本兼容情况的描述是 ie9+,即是 ie9 及更⾼的版本。经过测试,Vue 的核⼼框架 vuejs 本⾝,以及⽣态的官⽅核⼼插件(VueRouter、Vuex等)均可以在 ie9 上正常使⽤。
Vue 的作者尤⾬溪对于Vue 的学习建议 中有提及为了将项⽬更好的⽣态化/⼯程化,要尽可能学习及使⽤新的 ECMAScript 规范。⽬前ES6/ES2015 是可⽤度和稳定度较⾼的规范,⽂档齐全,国内还有 阮⼀峰 《ECMAScript 6 ⼊门》 做了⼤量的⽂档翻译,开发环境可谓完善。然⽽版本较旧的浏览器并不⽀持 es6 规范,尤其是 ie 浏览器,即使是最⾼的 ie11 版本,对于 es6 规范也⽀持得并不全。如此则需要对所有原⽣不⽀持 ES6 特性的
本⽂将针对使⽤ Vue ⽣态
ES6兼容
在 ie9 的环境上,es6 的部分新对象、表达式,并不⽀持,解决⽅案是使⽤babel-polyfill组件,它可以将 es6 的代码翻译成低版本
npm i babel-polyfill --save-dev
安装完成后,在项⽬的主⼊⼝⽂件 main.
import 'babel-polyfill';
在项⽬使⽤ vue-cli ⽣成的代码中,根⽬录有⼀个 .babelrc ⽂件,这是项⽬使⽤ babel 的配置⽂件。在默认⽣成的模板内容中,增加"useBuiltIns": "entry"的设置内容,这是⼀个指定哪些内容需要被 polyfill(兼容) 的设置
useBuiltIns 有三个设置选项
false – 不做任何操作
entry – 根据
usage – 检测代码中ES6/7/8 等的使⽤情况,仅仅加载代码中⽤到的 polyfill
这⾥推荐设置为entry,完整的.babelrc内容如下:
{
"presets": [
[
"env",
{
"modules": false,
"useBuiltIns": "entry"
}
],
"stage-3"
]
}
加⼊这些代码后,⼯程⾥的⼤部分内容已可兼容到 ie9 版本
Number对象
即使在使⽤babel-polyfill做代码翻译后,发现还是有⼀些 es6 的新特性并没有解决,⽐如说 Number 对象的parseInt 和 parseFloat⽅法
es6 将全局⽅法parseInt() 和parseFloat(),移植到 Number对象上⾯,⾏为完全保持不变。这样做的⽬的,是逐步减少全局性⽅法,使得语⾔逐步模块化。
解决这个问题不需要引⼊包来解决,同样在项⽬主⼊⼝⽂件 main.babel-polyfill之后 )
if (Number.parseInt === undefined) Number.parseInt = window.parseInt;
if (Number.parseFloat === undefined) Number.parseFloat = window.parseFloat;
requestAnimationFrame⽅法
requestAnimationFrame的优势,在于充分利⽤显⽰器的刷新机制,⽐较节省系统requestAnimationFrame 的基本思想就是与这个刷新频率保持同步,利⽤这个刷新频率进⾏页⾯重绘。此外,使⽤这个API,⼀旦页⾯不处于
不过有⼀点需要注意,requestAnimationFrame 是在主线程上完成。这意味着,如果主线程⾮常繁忙,requestAnimationFrame的动画效果会⼤打折扣。
有部分第三⽅组件就使⽤了这个⽅法,例如部分⽂件上传、图⽚处理类的组件;那么在这类型的组件在 ie9 下使⽤时,会报出
SCRIPT5007: Expected object.
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !questAnimationFrame; ++x) {
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
|| window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!questAnimationFrame)
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
nginx部署前端项目lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
Gist:requestAnimationFrame polyfill
这部分代码同样是尽可能在⽹站⼊⼝处就执⾏
http⽹络请求(跨域)
在⼤多数的
既然是前后端分离,那么部署也必然是各⾃独⽴部署,不同的访问路径,就会产⽣跨域访问的问题(同⼀站点,不同端⼝号也是跨域)
在此设定背景情况:
服务端已完整开启 CROS 跨域⽀持
http 组件使⽤ axios
axios 设置 withCredentials 为 true 开启跨域访问时携带 cookie 数据
⾼版本浏览器(ie10+ 或 chrome, ff)仅需要完成背景情况中的功能,即可⽀持跨域数据请求功能
axios 进⾏数据请求时,默认使⽤ XMLHttpRequest 对象,在检测到当前请求是跨域访问时,axios 会测试浏览器是否⽀持XDomainRequest 对象,若⽀持则优先使⽤。
ie8 / ie9 的 XMLHttpRequest 对象,不⽀持跨域访问,该对象在 ie10 后才原⽣⽀持跨域访问。微软的解决⽅案是在 ie8 / ie9 中提供了XDomainRequest(XDR) 对象来进⾏解决跨域问题,虽然使⽤该对象可以跨域访问成功,并返回数据,但它却依然是⼀个功能不完整的半成品,它的使⽤有诸多限制:
XDR 仅⽀持 GET 与 POST 两种请求⽅式
XDR 不⽀持⾃定义的请求头,若服务端使⽤ header 的⾃定义参数进⾏做⾝份验证,则不可⽤
请求头的 Content-Type 只允许设置为 text/plain
XDR 不允许跨协议的请求,如果⽹页在 HTTP 协议下,就只能请求 HTTP 协议下的接⼝,不能访问 HTTPS 接⼝
XDR 只接受HTTP/HTTPS 的请求
发起请求的时候,不会携带 authentication 或 cookies
微软虽然提供了解决⽅案,但却是不折不扣的鸡肋,根本⽆法胜任系统中各种场景的数据请求需求,⾄此,axios 对 ie9 的跨域数据请求已⽆能为⼒。
完美解决⽅案:代理(proxy)
虽然 axios 对 ie9 跨域已⽆能为⼒,但前端项⽬打包的解决⽅案 webpack 提供了⼀个优雅⽽彻底解决问题的⽅式:代理
devServer.proxy
webpack 的 devServer.proxy的功能是由http-proxy-middleware 项⽬来实现的
实现原理是将⽬标位置的请求代理为前端服务本地的请求,既然是代理成为本地的请求,就不存在跨域的问题,axios 就会⽤回XMLHttpRequest对象进⾏数据请求,⼀切都恢复正常了,header、cookies、content-type、authentication 等内容都被正确传递到服务端。
项⽬中 fig.
devServer: {
historyApiFallback: true,
noInfo: true,
overlay: true,
proxy: {
'/api': {
target: '
配置中指定了将
即是 /api 的前缀代表了服务端,所以在使⽤ axios 时,需要对每个服务端请求都增加上 /api 的前缀;通常在项⽬
不过,webpack 的devServer.proxy仅在开发模式下可⽤,⽣产模式下⽆法使⽤。开发模式下,调试服务可以读取 fig. 中的配置内容进⾏实时代理,⽽项⽬在部署到⽣产环境前,需要将⼯程进⾏编译转换成静态的
nginx 配置
虽然 devServer.proxy 的功能仅能⼯作于开发模式,那么在⽣产模式下,⾃然也是有解决⽅案的;通常 Vue 的项⽬在编译成最终的
f ⽂件配置增加以下内容
location /api/ {
}
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论