zoukankan      html  css  js  c++  java
  • Uploadify跨域上传原理

    我最近在用 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和策略文件实现了跨域上传.

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

  • 相关阅读:
    容器 list
    迭代器
    排序
    extern "C"
    FZU2127
    HDU1102--最小生成树
    HDU1102(最小生成树Kruskal)
    并查集详解(转自一个很有才的大神)膜拜
    C# switch
    Dijkstra(歪果仁的名字真是长。。。)
  • 原文地址:https://www.cnblogs.com/rmbteam/p/2255720.html
Copyright © 2011-2022 走看看