如何替代即将淘汰的Flash⽅案?
欢迎⼤家前往,获取更多腾讯海量技术实践⼲货哦~
本⽂由发表于
| 导语 Web技术飞速发展的如今,我们在感受新技术带来的便捷和喜悦的同时,也时常在考虑着⼀个问题:⽼技术如何迁移。正如本⽂的主题⼀样,Flash技术在早年风靡在Web领域,曾经发挥着⽆尽⼒量的⼀个⼯具正逐渐失去了其重要性。由于性能,兼容性,版权问
题,Flash的市场正在消退,曾经靠Flash实现的功能和特性如何完美得进⾏迁移呢,本⽂将简单谈⼀谈Flash的⼏个常见的特性的替代⽅案。
1.视频播放(Play Video)
我们知道Flash可以播放.swf⽂件的动画视频,⽽且具有很强的控制功能,以前很多Web视频播放器都是基于Flash去实现的。包括embed 标签,都是如此。所有视频源为swf的⽂件的视频都需要借助Flash去播放。
解决⽅案:
在移动端设备上,使⽤HTML5的video标签基本没有问题。 在PC上,IE低版本(IE8-)浏览器上除了Flash⽬前没有其它办法 在PC
上,IE9+和其它现在浏览器,采⽤HTML5标签。 综合来说,可以统⼀⽤以下⼀段代码实现兼容:
<video width="400" height="300" controld>
<!--  mp4格式适⽤于IE9+,Chrome,Safari -->
<source src="test.mp4" type="video/mp4"></source>
<!--  ogg格式适⽤于FireFox,Opera,Chrome -->
<source src="" type="video/ogg"></source>
<!--  webm格式适⽤于FireFox,Opera,Chrome -->
<source src="test.webm" type="video/webm"></source>
<!--  object需要Flash⽀持,当IE8-时考虑 -->
<object data="test.mp4" width="400" height="300">
<!--  embed需要Flash⽀持,当IE8-时考虑 -->
<embed src="test.swf" width="400" height="300">
</object>
</video>
2.跨域请求(Corss Origin Request)
2.1使⽤Flash进⾏跨域请求的⽅案实现
⽬前在PC端a.qq的页⾯请求b.qq的⼀个接⼝是理论上跨域的⼀个请求,旧版本浏览器特别是只⽀持XMLHTTPRequest Level1的浏览器,需要访问跨域请求,要么使⽤jsonp,要么只能使⽤Flash。 使⽤Flash进⾏跨域需要做的事情是
1.a.qq的js与Flash交互
2.Flash校验安全性,检查b.qq下根⽬录的l⽂件的控制访问属性
3.Flash作为中
间代理请求b.qq 4.Flash将请求结果返回给a.qq的js 图1简明扼要的描述了这个过程。
图1 Flash跨域请求
2.2 去Flash跨域如何实现
情况⼀:CORS(Cross-Origin Resource Sharing)【后端需改造】
条件:要使⽤CORS,必须在⽀持XmlHttpRequest Level2的浏览器中(IE10+和其它现代浏览器) 做法:设置withCredentials头,然后结合后台设置的Access-Control-Allow-Origin头进⾏控制,进⾏跨域即可。相关代码如下: 前端JS:
$.ajax({
url:"b.qq/api/xxx.php",
type:"POST",
xhrFields:{
withCredentials:true
},
success:function(){
//...
},
fail:function(){
//...
}
})
后端PHP:
<?php
//b.qq的接⼝中添加Access-Control-Allow-Origin头
header("Access-Control-Allow-Origin:a.qq");
access被淘汰了吗情况⼆:中转代理请求【建议】
我们回到同源策略,如果要请求b.qq下的⼀个接⼝,我们从b.qq下的页⾯发起请求,是遵循同源策略的。那么我们可以在接⼝域名下放⼀个统⼀的html⽂件,⽤于代理我们请求b.qq的接⼝,然后将结果告诉a.qq就可以了。 这种情况下要解决2个主要问题:1.cookie如何发送 2.a.qq与b.qq的代理页⾯前端通信 其实两个问题是⼀个问题,a.qq下的cookie我们是可以获取到的,同样的cookie我们可以种在b.qq下的。问题归结到第⼆个问题,如何在前端实现a.qq和b.qq两个页⾯之间的通信。 有两个⽅法:
1.使⽤HTML5规范的PostMessage特性
主要核⼼逻辑代码可以参考: 【a.qq页⾯代码】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
</body>
</html>
【b.qq页⾯代码】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
</body>
</html>
以上demo简单解决了前端跨域通信,跨域带cookie等问题,在逻辑上完全可以实现跨域通信。但是对于不⽀持PostMessage特性的⽼版浏览器是⾏不通的。⽐如IE8-浏览器就不能很好的⽀持PostMessage特性。这种情况下我们采⽤另外⼀种中转跨域的⽅案:降⼦域通信。下⾯介绍第⼆种⽅法:降⼦域通信:
2.不⽀持PostMessage时,降⼦域通信
由于a.qq和b.qq都是属于qq下的⼦域,同源策略在前端页⾯中判定依据是document.domain⽽不是location.host。⽽document.domain可写,可以⼈为更改到其⽗域名。这样a.qq和b.qq的两个页⾯都可以⾃⾏降到qq。这样就可以直接进⾏通信。 主要核⼼逻辑代码可以参考: 【a.qq页⾯代码】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
</body>
</html>
【b.qq页⾯代码】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
</body>
</html>
在实际改造过程中,如果后端结果过多,或者改造不⽅便,可以直接采⽤第⼆种⽅式——中转代理的⽅式进⾏改造。其原理⽰意图总结如下:
图2 去Flash跨域请求改造指导图
3.⽂件上传
3.1 背景
其实⽂件上传是HTML规范内的,理论上不需要使⽤Flash去做。但是随着ajax技术的兴起,Web 2.0时代的到来,input表单的提交改成ajax提交,页⾯⽆刷新的形式。但是这种形式下对于⽂件这类⼆进制⽂件⽆法提交,IE下本来有ActiveX 的FSO可以操作,但是插件的执⾏需要IE安全机制允许,很多情
况下⽤户体验不好,⽽且兼容性也不是很好。于是这种背景下,FLash⼜担当起了⼀个新的功能:⽂件上传。著名的jquery插件,ajaxupload.js就是⽤的Flash进⾏⽂件提交。
3.2去Flash上传
如何不使⽤Flash,上传⽂件,⽽且保证页⾯不刷新,是我们在去Flash上传⼯作中需要做的核⼼。下⾯针对不同的浏览器提供两套⽅案:3.2.1 【第⼀套⽅案】HTML5获取⽂件信息⽤FormData提交
条件:⽀持HTML5 FileReader 和FormData 特性 做法:
1.获取input表单的files对象
2.实例化FileReader对象,并解析files对象
3.解析之后输出base64编码的⽂件数据
4.base64的数据
传⼊FormData 5.ajax提交FormData
参考demo如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<input type="file" name="test" id="test" />
</body>
</html>
3.2.2 【第⼆套⽅案】低版本浏览器中⽤模拟表单提交
条件:⽆任何条件,⽀持任何浏览器 做法:
1.在页⾯上构建⼀个隐藏的iframe
2.在页⾯上构建⼀个form表单,表单中包含⽂件表单和其它附加字段表单,target设为上述iframe
的id 3.上传⽂件动作触发时,调⽤form的submit⽅法 4.iframe中加载上传cgi,返回结果与⽗窗⼝通信,如果iframe与cgi跨域,则参考【第⼆部分:跨域请求】进⾏处理
参考demo如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DEMO-上传⽂件</title>
</head>
<body>
<!-- 以a.qq上传到b.qq/upload/为例 -->
<form action="b.qq/upload/" enctype="multipart/form-data" method="post" target="postframe" name="fileform">
<!-- ⽂件上传按钮 -->
<input type="file" name="file_1" />
<!-- 隐藏的附加字段 -->
<input type="hidden" name="sExtend1" value="test1" />
<input type="hidden" name="sExtend2" value="test2" />
</form>
</body>
</html>
总结 本⽂给出了笔者在实际⼯作中遇到的最常见的去Flash改造的三种场景,现以表格的形式简单概括如下:
现代H5早期低版本IE等
视频播放使⽤H5的video标签没办法只能使⽤FLash,如果不⽤Flash,建议提醒⽤户升级浏览器
跨域提交请求使⽤CORS,前后端结合中转代理(PostMessage或者降域)
Ajax⽂件上传使⽤FileReader+FormData封装模拟表单提交到iframe
结语

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。