永利最大(官方)网站

Jquery基于ActiveX的批量上传

原创|其它|编辑:郝浩|2009-12-31 11:12:18.000|阅读 2674 次

概述:由于技术和经验有限,我一直不敢把文章发到永利最大(官方)网站(除了第一次发文不清楚状况点错了之外)。这次壮着胆子喝了二两雪碧,我也豁出来了,大家看了要是觉得没什么技术含量的话,就当这篇文章是个小笑话也就是了~

#慧都22周年庆大促·界面/图表报表/文档/IDE/IOT/测试等千款热门软控件火热促销中>>

  由于技术和经验有限,我一直不敢把文章发到永利最大(官方)网站(除了第一次发文不清楚状况点错了之外)。这次壮着胆子喝了二两雪碧,我也豁出来了,大家看了要是觉得没什么技术含量的话,就当这篇文章是个小笑话也就是了~
  在做这个功能之前参考了很多网上的文章,能试的基本都试了,发现没有完全正确的,大部分也是转来转去的,比如:《JQuery+ajax实现批量上传图片》。实现的思想就是客户端选好了路径,传到服务器端接收然后实现上传。
  这样在本地做是没有任何问题的,(因为本地做服务器和客服端都是你自己的电脑)
而大部分的人看到这基本也不会真正的拿来用然后发布到网上,只是在本地练练手而已。

  但是一旦你发布之后,就会发现这个思路从根本上就是错的:用服务器端的方法接收客户端的文件路径,再用这个路径找文件,根本就找不到。因为服务器找到的是服务器本机的文件。(服务器和客户端已经分离)
而实现了这个功能的网站基本都找不到相应的实现细节,(比如曾经的网易网盘功能,还有现在的摇篮网的space空间上传)
  在这里抛砖引玉,希望大家一起讨论,也希望有网盘和批量上传经验的兄弟多多指点。


  先看看我要实现的功能和效果:(上传完毕会生成成功和失败两个文件夹)(这已经是我发布到内网服务器后的效果)


流程:
点击自动上传--弹出浮动窗口,展示本地磁盘--选择磁盘--列出该磁盘下所有文件夹--选择一个文件夹--点击确定--上传


  这里一个麻烦之处就是由于种种原因,你无法使用服务器端的fileupload控件或者客户端的input type=file控件
这样的话就无法在服务器端用Request.File接收文件,那该如何实现?

  由于用户要求选择文件夹而不是文件,所以我用不了任何控件,只能通过js构建本机文件目录,
最开始我使用了一个Jquery插件:jqueryFileTree。

  插件详细和下载请见:     。里面有使用说明和demo(英文,是个老外做的),老实说效果很好,只不过不适合我要实现的功能(用户选择服务器文件有何用?)
  实现原理是通过ajax在cs方法中构建目录串输出html。这里就遇到了之前提到的问题,用服务器方法只能获取服务器的文件路径,发布之后无效。所以无法通过ajax方式获取文件的html串,只能用纯js构建。
  我改造一下这个插件,这里要使用一个ActiveXObject:Scripting.FileSystemObject,是js中用来访问本机文件的插件。网上可以搜到这个插件下的方法和属性,但是不够全面,很多方法要通过自己调试js时查看变量方法和属性列表的方法找到。利用这个插件我改造了jqueryFileTree,让它变成一个纯js访问本机文件目录。

  注:此ActiveXObject的用法参照了这篇文章:

里面有很多Scripting.FileSystemObject下面的方法和属性。


  主要改造了showTree方法:

 

  filetree
   function showTree(c, t) {
                    $(c).addClass(
'wait');
                    $(
".jqueryFileTree.start").remove();
        ;            
var a = new Array;
                    t 
= unescape(t);
                    
var fso, f, fc, a;
                    fso 
= new ActiveXObject("Scripting.FileSystemObject");

                    $(
'#inputpath').val(t);
                   ; f 
= fso.GetFolder(t);
                    ;fc 
= new Enumerator(f.SubFolders);

                    
for (; !fc.atEnd(); fc.moveNext()) {
                        ;a[a.length] 
= fc.item();
                    }
                    a 
= (a);
                    
for (var i = 0; i < a.length; i++) {
         &nbsp;              
var str = "<ul class='jqueryFileTree' style='display: none;'><li class='directory collapsed'><a href='#' rel='" + a[i] + "/'>" + a[i] + "</a></li></ul>";
   &nbsp;                    $(c).removeClass(
'wait').append(str);
                    }
 ;             &nbsp;     
if (a.length < 1) {
          &nbsp;             $(c).removeClass(
'wait');
                    }
                    $(c).find(
'.start').html('');
              &nbsp;     
if (o.root == t) $(c).find('UL:hidden').show();
            &nbsp;       
else $(c).find('UL:hidden').slideDown({ duration: o.expandSpeed, easing: o.expandEasing });

                    bindTree(c);
&nbsp;    ;           }

 

 

前台html
<form id="form1" runat="server">
    
<div>
    
      &nbsp;  
<div style="width:978px;padding:1px;margin:10px auto;background:#00a8fe;">
        
<div style=&quot;border:1px&nbsp;solid #fff;font-size:14px;">
    &nbsp;   
<div style="background:#edf9ff;height:35px;padding:0 15px 0 15px;line-height:35px">
          &nbsp; 照片上传:
<input id="File1" runat="server" name="File1"  size="44" type="file" />   
         &nbsp;  
<asp:Button ID="Button_upload" runat="server" Text="上 传"   onclick="Button_upload_Click" />                  
               &nbsp;        
<input id="chkAutoUpload" type="checkbox" onclick="showOrhidden()" />自动上传&nbsp;
          &nbsp;     
</div>
 &nbsp;      
</div>
    
    
</div>
    
    
<%--浮动层--%>
    
<div id="divfloat">
  &nbsp;     
<id="closeX" href="javascript:closethis()" onmouseover="this.innerHTML='关闭'" onmouseout="this.innerHTML='×'">×</a> 
       &nbsp;
<div id="divaddfirst">
           
           &nbsp;
<input id="lblselect" class="inputlbl" type="text" value="选择需上传图片所在的文件夹" />
   &nbsp;         
<input id="lblweb" style="width:230px;" disabled="disabled" class="inputlbl" type="text" value="(此功能需要加本站点为可信任站点)" /><br />
        ;    
<span style="color:Red; font-size:14px;">您选择的上传图片所在路径为:</span>
            
            
    ;      &nbsp; 
<input id="inputpath" class="inputlbl" type="text" value="" disabled="disabled"  style=" width:320px;font-weight:bold; font-size:16px;" />
           &nbsp;
<input type="checkbox" id="chkIsTj" />特检照片
     &nbsp;      
<ul>
        ;    
<li id="liC" class="diskli">
     &nbsp;          
<img src="Images/FolderImg/disk.jpg" alt="" onclick="choosefolder('C')" style="cursor:hand;" />
           &nbsp;    
<id="hrefC" style="color:Black; font-size:medium&nbsp;"  href="javascript:choosefolder('C')">本地磁盘 (C:)</a>
 &nbsp;         &nbsp;    
<div id="divContainerC" class="divContainer"></div>
     &nbsp;      
</li>
    &nbsp;       
<li id="liD" class="diskli">
                
<img src="Images/FolderImg/disk.jpg" alt="" onclick="choosefolder('D')" style="cursor:hand;" />
&nbsp;               
<id="hrefD" style="color:Black; font-size:medium "  href="javascript:choosefolder('D')">本地磁盘 (D:)</a>
     &nbsp;          
<div id="divContainerD" class="divContainer"></div>
  &nbsp;         
</li>
  &nbsp;         
<li id="liE" class="diskli">
   &nbsp;            
<img src="Images/FolderImg/disk.jpg" alt="" onclick="choosefolder('E')" style="cursor:hand;" />
       &nbsp;        
<id="hrefE" style="color:Black; font-size:medium "  href="javascript:choosefolder('E')">本地磁盘 (E:)</a>
   ;         ;    
<div id="divContainerE" class="divContainer"></div>
     &nbsp;  &nbsp;   
</li>
&nbsp;           
</ul>
&nbsp;            
<href="javascript:selectconfirm()" style=" position:absolute; bottom:20px; left:300px; font-size:16px; font-weight:bold;">选择完毕</a>
        &nbsp; ;  
<input id="input2" class="inputlbl" type="text" value="上传中,关闭当前页将停止上传...上传日志信息保存在网站根目录下Logs\AutoUploadPhoto_Exception.txt" disabled="disabled"  style=&quot; display:none;position:absolute; bottom:10px; left:20px; width:600px; color:Red;" />
     &nbsp;      
<input id="hidinput" style="display:none;" value="0" /> 
         
</div>
    
</div>
    
<div id="divfloatbg"></div>
    
</div>
    
</form>

 

 

  浮动效果的实现网上有很多,方法:

浮动
//悬浮层显示
        function showOrhidden()
        {
            var w = document.documentElement.clientWidth; //宽
            var h = document.documentElement.clientHeight; //高
            var tw = $("#divfloat").width();
            var th = $("#divfloat").height();
            $("#divfloat").css({ "position": "absolute", "top": h / 2 - th / 2, "left": w / 2 - tw / 2 });
            if ($("#chkAutoUpload").attr("checked") == true)
            {
                $("#divfloatbg").css("opacity", "0.5"); //透明度
                $("#divfloatbg").fadeIn("slow"); //缓慢淡出
                $("#divfloat").fadeIn("slow");
            }
            else
            {
                $("#divfloatbg").fadeOut("slow");
                $("#divfloat").fadeOut("slow");
            }
&nbsp; &nbsp;     }

 

 

  点击文件夹按钮事件:

代码
 //选择本地文件夹上传相片
        function choosefolder(disk)
        {
   ;        &nbsp;$(
".divContainer").html(""); //清空
        &nbsp;   var divContainer = '#divContainer' + disk;
       &nbsp;    
//构建div目录树
 &nbsp;          $(divContainer).fileTree({ root: disk + ':\\', multiFolder: false }, function(file)
            {
&nbsp;               
//alert(file);
            });
       ;  }

 

  改造好之后已经可以实现这样的功能:传入一个盘符号,会列出所有该盘符的所有文件夹,继续点击会继续列出相应文件夹的子文件夹(和windows文件效果类似)。


   接下来要实现上传。没有控件就不能直接接受file,又不能接收路径查找文件,那么只能把文件整个传到服务器端。思路是将文件转成base64流,再通过ajax传到服务器端(这里要用到另一个插件MSXML2.DOMDocument),然后服务器端Request.InputStream接收,然后用XML处理这个流,之后base64解码,然后继续你的上传流程就可以了。

代码
//选择完成后确定按钮事件
        function selectconfirm()
        {
        ;    
var localpath = $("#inputpath").val();
    &nbsp;       
var leaving = $("#LblYue").text();
  &nbsp;         
var tj = $("#chkIsTj").attr("checked"== true ? "1" : "0";
    &nbsp;    &nbsp;  $(
"#input2").show();
      &nbsp;     $(
"#hidinput").val("1");
            upload(localpath, leaving, tj);
        }
    
    
     &nbsp;  
//上传和文件夹操作
        function upload(localpath, leaving, tj)
        {
 ;          &nbsp;
var fso, f, fc, a;
           ; fso 
= new ActiveXObject("Scripting.FileSystemObject");
    &nbsp;       f 
= fso.GetFolder(localpath);

   &nbsp;        
if (!fso.FolderExists(localpath + "\\Success"))
            {
       ;       &nbsp; fso.CreateFolder(localpath 
+ "\\Success");
            }
      ;      
if (!fso.FolderExists(localpath + "\\Fail"))
            {
&nbsp;          &nbsp;    fso.CreateFolder(localpath 
+ "\\Fail");
            }

         &nbsp;  ff 
= new Enumerator(f.files);
        &nbsp;   
for (; !ff.atEnd(); ff.moveNext())//枚举所有文件   
            {
          &nbsp;     s 
= ff.item();   //取文件对象
                alert(s);
                uptowebmethod(s.Path, leaving, tj, f.Path, localpath);
            }
        }
        
       &nbsp;
//文件->流->XML->ajax传入后台
        function uptowebmethod(path, leave, istj, fpath, localpath)
        {
   &nbsp;      &nbsp; 
var ado_stream = new ActiveXObject("ADODB.Stream");
       &nbsp;&nbsp;   
var xml_dom = createXMLDOM();

&nbsp;           xml_dom.loadXML(
'<?xml   version=&quot;1.0" ?><root/>');
            xml_dom.documentElement.setAttribute(
"xmlns:dt""urn:schemas-microsoft-com:datatypes");
  &nbsp;&nbsp;        
var l_node1 = xml_dom.createElement("photo");
&nbsp;           l_node1.dataType 
= "bin.base64";

      ;      ado_stream.Type 
= 1;   //   1=adTypeBinary     
            ado_stream.Open();
            ado_stream.LoadFromFile(path);

    ;        l_node1.nodeTypedValue 
= ado_stream.Read(-1);   //   -1=adReadAll   
            ado_stream.Close();
            xml_dom.documentElement.appendChild(l_node1);

    &nbsp;        
var pnode = xml_dom.createElement("path");
            xml_dom.documentElement.appendChild(pnode);
      &nbsp;     pnode.text 
= path;

             
var lnode = xml_dom.createElement("leave");
            xml_dom.documentElement.appendChild(lnode);
    &nbsp;       lnode.text 
= leave;

         &nbsp;  
var tjnode = xml_dom.createElement("istj");
            xml_dom.documentElement.appendChild(tjnode);
           &nbsp;tjnode.text 
= istj;

      &nbsp;     
var fnode = xml_dom.createElement("fpath");
            xml_dom.documentElement.appendChild(fnode);
  &nbsp; ;        fnode.text 
= fpath;


            $.ajax({
 &nbsp;              type: 
"POST",   //访问WebService使用Post方式请求
           &nbsp;    //contentType: "application/json", //WebService 会返回Json类型
       &nbsp;        url: "AjaxForm1.aspx"//调用WebService的地址和方法名称组合 ---- WsURL/方法名
           &nbsp;    processData: false,
    &nbsp; &nbsp;         data: xml_dom,    
//这里是要传递的参数,格式为 data: "{paraName:paraValue}",下面将会看到
           ;     //dataType: 'json',
  ;              success: function(result)
        &nbsp;       {     
//回调函数,result,返回值
&nbsp;                   if (result == '0')
                    {
                        s.move(localpath 
+ "\\Fail\\" + s.name);
                    }
           &nbsp;        
else if (data == '1')
                    {
 ;                       s.move(localpath 
+ "\\Success\\" + s.name);
                    }
       &nbsp;           ; 
else
                    {
                        alert(result);
                    }
                }
            })
        }

 ;       
//创建XMLDOM
        function createXMLDOM()
        {
        ;    
var arr = ["MSXML2.DOMDocument.5.0""MSXML2.DOMDocument.4.0""MSXML2.DOMDocument.3.0""MSXML2.DOMDocument""Microsoft.XmlDom"];
 &nbsp;          
for (var i = 0; i < arr.length; i++)
            {
&nbsp;          &nbsp;    
try
                {
    &nbsp;           ;    
var xmlDom = new ActiveXObject(arr[i]);
   &nbsp;&nbsp;               
return xmlDom;
                }
                
catch (oError)
                {
 ;      &nbsp;            alert(
"error");
                }
            }
     &nbsp;      
throw new Error("MSXML is&nbsp;not install on your system.");
&nbsp;       }

 

   服务器端主要代码:

  

 

代码
#region Page_Load
        
protected void Page_Load(object sender, EventArgs e)
        {
            Stream photoStream&nbsp;
= Request.InputStream;
         &nbsp;  XmlDocument doc 
= new XmlDocument();

    &nbsp;       
if (Request.InputStream != null)
            {
                
//byte[] _tmpData = new byte[photoStream.Length];
  &nbsp;      ;       
//photoStream.Read(_tmpData, 0, Convert.ToInt32(photoStream.Length));
   &nbsp; &nbsp;          
//string request1&nbsp;= System.Text.Encoding.UTF8.GetString(_tmpData);&nbsp;



                doc.Load(photoStream);
     &nbsp;    &nbsp;     XmlNode nod 
= doc.DocumentElement.SelectSingleNode("path");
                 Paths 
= nod.InnerText;

           &nbsp;    nod 
= doc.DocumentElement.SelectSingleNode("fpath");
              ;  
string fpath = nod.InnerText;

             ;   nod 
= doc.DocumentElement.SelectSingleNode("leave");
                
string leaving = nod.InnerText;

 &nbsp;            &nbsp; nod 
= doc.DocumentElement.SelectSingleNode("istj");
         &nbsp;      
string istj = nod.InnerText;

                
string photoXML = doc.DocumentElement.SelectSingleNode("photo").InnerText;

     &nbsp;          
byte[] photo = Convert.FromBase64String(photoXML);


            &nbsp;  &nbsp;
//去除xml中的多余标签和属性,转化为stream
                MemoryStream stream = new MemoryStream();
 ;               XmlDocument docphoto 
= new XmlDocument();
              &nbsp; 
char[] str = photoXML.ToCharArray();
          &nbsp;     
for (int i = 0; i < photo.Length; i++)
                {
                    stream.WriteByte(photo[i]);
                }
                docphoto.Save(stream);


     &nbsp;          
if (!string.IsNullOrEmpty(Paths))
                {
          &nbsp;       &nbsp; 
//存入cookie
                   &nbsp;HttpCookie cookie = Request.Cookies["Path"];
        ;            
if (cookie == null)
                    {
                        cookie 
= new HttpCookie("Path");
                    }
                     cookie[
"path"= fpath;
                    cookie[
"istj"= istj;
               &nbsp;    cookie.Expires 
= DateTime.Now.AddDays(100d);
                    Response.Cookies.Add(cookie);

                    UploadPh(Paths, leaving, istj, stream);//在此方法处理你的上传
                }
            }
 &nbsp;      }
#endregion

 

  目前此方法有三大问题:
  1.不同的浏览器安全级别略有区别,activex经常会弹出提示,影响用户体验,有的还需要用户设置本站点为信任站点。
  2.除IE外别的浏览器无法使用
  3.IE有一个补丁对ADODB.Stream进行了限制使用,如果你一直开了自动更新或打了这个补丁,会弹出js错误:automation无法在服务器创建。其实就是ADODB.Stream无法创建对象造成的。
  解决方法:打开注册表编辑器
  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\
把{00000566-0000-0010-8000-00AA006D2EA4} 项删除或修改键值为任意值(除了400),这样你的ADODB.Stream就可以创建成功了。

  css我就不贴了。大家有什么好的方案尽管拿出来~


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@hmdbvip.cn

文章转载自:博客园

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP
PM娱乐城网络现金网站(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) PM娱乐城最大(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) 永利外围最新(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) 网络权威朗驰娱乐大全(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) 永利真人网上足球(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) 利记最火十大网(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) boyu·博鱼权威网络足球(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) PM娱乐城网上足球(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新)