回头再说:Uploadify跨域上传原理

本文涉及的产品
.cn 域名,1个 12个月
简介:

 

《 回头再说:jQuery跨域原理 》一文提到浏览器的同源策略以及使用JsonP的方式实现跨域;在评论中金色海洋提出了一个问题:

 

我最近在用 uploadify + ashx 来做文件上传的功能。都测试成功了,但是发现我可以提交到其他的网站里面。

我是在本地测试了。两个网站,IP地址相同,使用端口来区分。

一个端口是8001,另一个是8002 。

两个网站都有上传文件的程序,我发现,如果我把8001端口的站点的

'script': '/_CommonPage/UploadHandler.ashx',

改成

'script': 'http://192.168.0.1:8002/_CommonPage/UploadHandler.ashx',

居然也能够成功上传文件,传到了8002对应的网站里面。

我不知道如果换成域名了,是否也是可以往不同的域名里上传文件?

如果是的话,是不是很危险?如何来验证呢? 

 

 我给出的错误解释

         看到金色海洋的问题之后,我下载下来Uploadify源码看了一下,然后非常草率的给出了一个解释,点击这里;对于这个错误的解释,园友mx1700提出了质疑;于是下班回家之后,我开始动手模拟金色海洋的环境,试图一探究竟; 

 

Uploadify工作机制

       我在VS2010里面新建了一个webApplication,在页面上使用Uploadify,页面代码如下:   

    

复制代码

  
  


< script src ="Scripts/jquery-1.4.1.js" type ="text/javascript" ></ script >
< script src ="Scripts/jquery.uploadify.v2.1.0.js" type ="text/javascript" ></ script >
< script src ="Scripts/swfobject.js" type ="text/javascript" ></ script >
< script type ="text/javascript" >
// <![CDATA[
var id = " 55 " ;
var theString = " asdf " ;
$(document).ready(
function () {
$(
' #fileInput ' ).uploadify({
' uploader ' : ' uploadify.swf ' ,
' script ' : ' http://www.b.com:84/Uploader.ashx ' ,
' scriptData ' : { ' id ' : id, ' foo ' : theString },
' cancelImg ' : ' cancel.png ' ,
' auto ' : true ,
' multi ' : true ,
' fileDesc ' : ' Image Files ' ,
' fileExt ' : ' *.jpg;*.png;*.gif;*.bmp;*.jpeg ' ,
' queueSizeLimit ' : 90 ,
' sizeLimit ' : 4000000 ,
' buttonText ' : ' Choose Images ' ,
' folder ' : ' /uploads ' ,
' onAllComplete ' : function (event, queueID, fileObj, response, data) {

}
});
});
// ]]></script>

< input id = " fileInput " name = " fileInput " type = " file " / >
复制代码

 

        通过单步调试,我发现页面上会通过swfobject. js动态加载一个Flash, 我们在页面上操作的实际上是Flash.  jQuery的作用是页面、Flash、 目标服务器之间的黏合剂。 它定义用户上传操作在不同时机的响应函数.而在 这里  我所认为“ 发送数据上传文件”的函数, 只不过是一个用来检查服务器上是不是已经存在同名文件的函数; 由于这个检查有可能是跨域,所以  Uploadify间接使用了jQuery的JsonP跨域解决 方案.

        通过排除,我们能有一个基本的判断:文件上传是在Flash里面完成的.那么Flash里面做了什么呢?还好有uploadify.fla文件,使用Flex Builder打开这个文件来看,果然如此,很多朋友没有Flex Builde,这里贴出完整代码;可以看到,

1
// Upload each file<br>function uploadFile(file:FileReference, index:int, ID:String, single:Boolean):

    实际的上传操作,而上传不同时机使用的很多函数都是定义在jquery.uploadify.v2.1.0.min.js文件里面.

uploadify.fla

       现在我们能够得出这样一个结论:Uploadify本质上是一个基于Flash的jQuery上传插件.那么它到底能不能跨域呢?这里我们要考虑两个安全模型.一个是浏览器的同源策略,jQuery与目标服务器的交互是过Jsonp方式来实现回避浏览器的同源策略。还有一个就是Flash的安全沙箱,分析之前我们还是先完成金色海洋想要的实验.

 

环境准备

       我们在IIS中部署两个站点,既然是验证跨域我们为这两个站点绑定主机头;

   站点A:www.a.com 端口83 站点B:www.b.com 端口84

   

   修改Host文件(文件位置c:\Windows\System32\drivers\etc\hosts)

 

127.0.0.1 www.a.com

 

127.0.0.1 www.b.com

   注意:为了避免偶然因素的影响,后面每一次修改之后我都会重启IIS,使用新的浏览器窗口进行测试。


  1. 首先验证两个站点是否正常运行:站点A使用'script': 'http://www.a.com:83/Uploader.ashx', 站点B使用'script': 'http://www.b.com:84/Uploader.ashx',即当前域页面上传到当前域.测试通过
  2. 将站点A上传的目标服务域修改成站点B,即修改'script': 'http://www.b.com:84/Uploader.ashx',测试结果见下面的截图

 

error 

    3.看到上面的Security Error了么,我们通过在站点B下面添加一个crossdomain.xml,该文件的内容如下:

复制代码

  
  
<? xml version="1.0" encoding="UTF-8" ?>
<! DOCTYPE cross-domain-policy SYSTEM
"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"
>
< cross-domain-policy >
< site-control permitted-cross-domain-policies ="all" />
< allow-access-from domain ="*" />
< allow-http-request-headers-from domain ="*" headers ="*" />
</ cross-domain-policy >
复制代码

 


   添加了这个文件之后,站点A上传文件到站点B成功!


Uploadify跨域原理

      上面通过添加了crossdomain.xml之后就实现了跨域上传文件,关键点在于Flash的安全沙箱策略;Flash安全策略简单讲:同一个域的属于同一个沙箱,同一个沙箱的可以互相访问.如果要访问另外一个沙箱的内容就要在另外一个沙箱定义信任,这种信任策略就定义在crossdomain.xml中。在我们的实验中就是在站点B的策略文件crossdomain.xml中定义了对站点A的信任,只不过我偷懒让站点B信任所有外部域名的访问。

     对于crossdomain.xml还有两点细节:1.这个文件的要放在站点的根目录下而且文件名固定 2.跨域访问端口在1024以下必须要通过策略文件来定义信任关系。换句话说端口大于等于1024隐式开放访问权限。策略文件的详细说明请点击这里查看。

 

总结   

    对于金色海洋的问题解答:之所以你可以上传到另外一个端口的站点时因为IP一样,如果是上传到另外一个域名下,需要再目标服务器的根目录下添加Flash安全策略文件.

     Uploadify本质上是一个基于Flash的jQuery上传插件.跨域上传的情况牵扯到两个安全模型,一个使浏览器的同源策略,一个使是Flash的安全沙箱策略;我们组合使用jQuery的Jsonp和策略文件实现了跨域上传.

     好吧,就到这里,周末愉快

 

     测试文件下载:Web1.rar crossdomain.xml

目录
相关文章
|
7月前
|
存储 前端开发 Windows
对于莫名其妙使用smarttomcat上传前端项目失败,上传css等静态资源失败等原因,及解决方法
对于莫名其妙使用smarttomcat上传前端项目失败,上传css等静态资源失败等原因,及解决方法
|
8月前
|
移动开发 前端开发 安全
Ajax跨域的所有方法(最详细带使用教程!!!)
Ajax跨域的所有方法(最详细带使用教程!!!)
|
移动开发 前端开发 HTML5
前端下载图片的N种方法
前端下载图片的N种方法
456 0
前端下载图片的N种方法
|
前端开发 JavaScript
|
中间件 开发工具 数据库
协同开发时巧用gitignore | 巧用中间件 避免网络请求时携带登录信息
今天分享一下:在多人协同开发中,如果大家都进行本地测试可能会出现的问题。
124 5
|
前端开发 内存技术
继续啃boostrap上传组件的uploadify
不管在哪个系统中,上传肯定是必不可少的,上一篇文章中介绍了uploadify中typeaheader用法,但是仍然存在一些用法,例如,Ajax和上一篇文章中的方法都是在上传一张图片就刷新了,然而很多情况下是上传一堆图片之后才刷新,所以继续研究。
88 0
继续啃boostrap上传组件的uploadify
|
数据采集 JavaScript 前端开发
网站流量日志埋点收集 —原理实现雏形—如何解决 js 跨域问题(伪装图片)|学习笔记
快速学习网站流量日志埋点收集—原理实现雏形—如何解决 js 跨域问题(伪装图片)
263 0
网站流量日志埋点收集 —原理实现雏形—如何解决 js 跨域问题(伪装图片)|学习笔记
又见跨域大坑....
又见跨域大坑....
281 0
|
前端开发 应用服务中间件 nginx
常用前端文件下载方法
经常在项目中会遇到需要下载文件的需求,根据不同的需求和项目实现情况,通常有以下几种做法。
常用前端文件下载方法
|
前端开发 JavaScript
#yyds干货盘点# 【js学习笔记九】前端异步请求逐步进行一回调
#yyds干货盘点# 【js学习笔记九】前端异步请求逐步进行一回调
106 0
#yyds干货盘点# 【js学习笔记九】前端异步请求逐步进行一回调

热门文章

最新文章

下一篇
开通oss服务