设为首页收藏本站订阅更新

无忧脚本

 找回密码
 加入无忧

QQ登录

只需一步,快速开始

搜索
查看: 4185|回复: 6

[原创] Javascript实现简单的asp版文字和多文件混合上传

[复制链接]
发表于 2013-3-21 11:50:07 | 显示全部楼层 |阅读模式
本帖最后由 Rimifon 于 2013-3-21 15:32 编辑

演示地址:http://www.fengyun.org/Test/Upload.asp
htmlfile能做神马?Google用它来做长连接,我们还能用它来做ASP上传
下面的代码仅创建了一个htmlfile的ActiveX对象,没做文件保存。
原理是利用了recordset的appendChunk方法来连续读取上传数据,解决IIS上传默认不允许超过200kb的问题,然后使用xml分析二进制内容。
上代码吧:

  1. <%@ language="javascript" codepage="65001" %><%
  2. Boot();
  3. function Boot()
  4. {
  5.         if(Request.QueryString("Mode").Item != "Down") return ShowForm();
  6.         // 文件下载处理
  7.         if(!Application("TempName")) return Response.Write("No File");
  8.         Response.addHeader("Content-Disposition", "Attachment;filename=\"" + encodeURIComponent(Application("TempName")) + "\"");
  9.         Response.addHeader("Content-Length", Application("TempSize"));
  10.         Response.BinaryWrite(Application("TempFile"));
  11. }
  12. function ShowForm()
  13. { %><!doctype html><html><head>
  14.         <meta charset="UTF-8" />
  15.         <title>文件上传</title>
  16.         <style type="text/css">
  17.         body{ font: 4mm/7mm simsun }
  18.         </style>
  19. </head><body><%
  20. var up = new UploadClass;
  21. if(Request.ServerVariables("REQUEST_METHOD").Item == "POST")
  22. {
  23.         var str = up.ReadForm();
  24.         if(str != "OK") Response.Write(str);
  25.         else
  26.         {
  27.                 var data = up.Form("test");
  28.                 if(data[0].Data) Response.Write("您提交的文本为:" + data[0] + "<br />");
  29.                 if(data[1].File)
  30.                 {
  31.                         Response.Write("您上传的文件是:<a href=\"?Mode=Down\">" + data[1].File + "</a> (" + data[1].Size + " bytes)<br />");
  32.                         Application("TempFile") = data[1].Data;
  33.                         Application("TempSize") = data[1].Size;
  34.                         Application("TempName") = data[1].File;
  35.                 }
  36.         }
  37. }%><form method="post" enctype="multipart/form-data">
  38. 文本:<input name="test" /><br />
  39. 文件:<input name="test" type="file" />
  40. <input type="submit" value="上传" /><br />
  41. 当前最大允许上传 <%= up.MaxSize %> Bytes,支持的文件类型:<%= up.Filter %><%
  42. if(Application("TempName")) Response.Write("<br />当前的临时文件为:<a href=\"?Mode=Down\">" + Application("TempName") + "</a> (" + Application("TempSize") + " Bytes)");
  43. %>
  44. </form></body></html><% }

  45. /* 文件上传类,支持多文件及文字混合上传 */
  46. function UploadClass()
  47. {
  48.         this.MaxSize = 512 * 1024;
  49.         this.Filter = "jpg|png|gif|bmp|doc|docx|txt|zip|rar";
  50.         var data = new Object;        // 存储表单对象
  51.         this.ReadForm = function()
  52.         {
  53.                 var nmbTotal = Request.TotalBytes;
  54.                 if(nmbTotal > this.MaxSize) return "文件大小超过限制。";
  55.                 var strRule = Request.ServerVariables("Http_Content_Type").Item || "";
  56.                 strRule = (strRule.match(/boundary=(.+)/) || [])[1];
  57.                 if(!strRule) return "非文件上传表单";
  58.                 strRule = "2d2d" + strRule.replace(/[\w\-]/g, function($1){ return $1.charCodeAt(0).toString(16); });
  59.                 var xml = new ActiveXObject("htmlfile").createElement("xml");
  60.                 var root = xml.createElement("root"); root.dataType = "bin.hex";
  61.                 var rcd = xml.recordset; rcd.fields.append("bin", 205, -1);
  62.                 rcd.open(); rcd.addNew();
  63.                 var nmbByte = 0, nmbRead = 200000;        // 缓冲区大小
  64.                 while(Response.IsClientConnected() && nmbByte < nmbTotal)
  65.                 {
  66.                         rcd(0).appendChunk(Request.BinaryRead(nmbRead));
  67.                         nmbByte += nmbRead;
  68.                 }
  69.                 root.nodeTypedValue = rcd(0).value; rcd.close();
  70.                 var arr = root.text.split(strRule); arr.shift(); arr.pop();
  71.                 var reg = new RegExp("\\.(?:" + this.Filter + ")$", "i");
  72.                 for(var i = 0; i < arr.length; i++)
  73.                 {
  74.                         var nmbSplit = arr[i].indexOf("0d0a0d0a");
  75.                         // 此处仅支持UTF-8解码,gbk请借助rcd或流对象
  76.                         var strHead = arr[i].slice(4, nmbSplit).replace(/(\w{2})/g, "%$1");
  77.                         strHead = decodeURIComponent(strHead);
  78.                         var strPath = (strHead.match(/filename="(.+?)"/i) || [])[1] || "";
  79.                         strPath = (strPath.match(/([^\\\/]+)$/) || [])[1];
  80.                         if(strPath && !reg.test(strPath)) return "不允许的文件类型。";
  81.                         // 查找两个空行,忽略最后一个空行
  82.                         root.text = arr[i].slice(nmbSplit + 8, -4);
  83.                         var field = (strHead.match(/name="(.+?)"/i) || [])[1] || "";
  84.                         if(!data[field]) data[field] = new Array;
  85.                         data[field].push(
  86.                         {
  87.                                 File : strPath, Size : root.text.length / 2,
  88.                                 Data : strPath ? root.nodeTypedValue : decodeURIComponent(root.text.replace(/(\w{2})/g, "%$1")),
  89.                                 toString : function(){ return this.Data; }
  90.                         });
  91.                 }
  92.                 return "OK";
  93.         }
  94.         this.Form = function(strField)
  95.         {
  96.                 var item = data[strField] || [];
  97.                 return item.length < 2 ? item[0] : item;
  98.         }
  99. } %>
复制代码
 楼主| 发表于 2013-3-21 15:50:33 | 显示全部楼层
2013年还在玩asp,是不是有点outman了……
发表于 2013-3-21 17:19:45 | 显示全部楼层
重要的是思想,不过我对能否突破IIS的200K限制持怀疑态度

点评

200kb没问题的。:)  发表于 2013-3-21 20:09
发表于 2013-3-28 18:28:37 | 显示全部楼层
小龙 发表于 2013-3-21 17:19
重要的是思想,不过我对能否突破IIS的200K限制持怀疑态度

改下配置就行
发表于 2013-3-28 18:39:29 | 显示全部楼层
asp是有点out了,很多特殊功能不支持,例如:静态公共对象、httpxml性能不好。
反正就是性能不怎么好,我也用jscipt开发过网站,调用了各种http数据接口和数据库,加缓存,
经过各种优化后,现在只能说是凑合能支持日访问IP十多万,你们对这个优化有什么心得吗?
 楼主| 发表于 2013-4-7 20:19:01 | 显示全部楼层
缓存应该能解决问题。我一直觉得开发语言不是性能上的瓶颈,关键是在数据库的操作上面。
发表于 2013-4-9 09:15:16 | 显示全部楼层
Rimifon 发表于 2013-4-7 20:19
缓存应该能解决问题。我一直觉得开发语言不是性能上的瓶颈,关键是在数据库的操作上面。

有周期更新的,只能局部缓存东西,不同板块的内容缓存时间不一样。
新产生的页面也很多,都需要网络连接,这些连接都不能多线程的。
如果不符合时间的缓存需要更新,也需要时间的。

点评

想复杂了吧?一般将整个页面缓存30秒就差不多了。甚至可人工操控,除非管理员要求刷新,否则一直读缓存。  发表于 2013-4-10 11:28
您需要登录后才可以回帖 登录 | 加入无忧

本版积分规则

小黑屋|手机版|Archiver|无忧脚本 ( 苏ICP备05080427号 )|值班电话:027-62300445   鄂公网安备 42011102000433号

GMT+8, 2017-12-13 13:13 , Processed in 0.096481 second(s), 8 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表