这个仿163网盘无刷新文件上传系统,并没有用使用.net的控件,完全的手工制作。前台基本上是静态的,跟后台没有关系,所以后台用什么语言做都可以(后面有各个版本的实例下载)。
本来觉得这个系统会很复杂,但把每个部分都分析清楚后,其实需要的技术并不高。不过当我把各个功能函数都整理好准备进行封装时,却发现要把程序封装不是那么容易,因为程序跟html的耦合度太高。然后我逐步把程序中操作html相关的部分分离出来,首先把简单的分离,接着是文件列表,然后是file控件,最后是一些提示性程序。经过几次尝试才把整个结构封装好,现在程序结构应该算比较清晰,有什么不明白的地方欢迎留言。
效果预览
这里的预览只是前台的效果,要整个系统测试请下载完整实例。
程序说明
【无刷新上传】
要实现文件上传,form必须设置几个属性:
1.action:设为要处理数据的页面地址;
2.method:设为"post";
3.enctype/encoding:必须设为"multipart/form-data",这里要注意的是在ie中用js修改form的enctype属性是没有效果的,只能修改encoding;
后面两个属性程序初始化时都有设置:
this.Form.method = "post";
this.Form.encoding = "multipart/form-data";
要注意这里的无刷新不是ajax哦,而是利用“古老”的iframe。
由于ajax提交数据必须先获取数据,而js(一般情况下)是不能操作客户端文件,要获取文件数据就更不用说了,所以只能用iframe来做。
先说说iframe实现无刷新上传的原理:利用form的target属性,把数据提交到页面中一个(通常为隐藏的)iframe上。直观点说就是把“刷新”留给iframe。
其实原理跟一般用iframe实现无刷新提交表单是一样的,只是这里换成是文件。
这里关键就是把form的target设为iframe的name:
this.Form.target = this._FrameName;
【iframe】
如果没有自定义iframe,程序在初始化时会自动创建无刷新所需的iframe的。
首先必须选择一个iframe名,这在无刷新时是必须的,为了每个实例能创建各自的iframe,这里用了一个随机数:
this._FrameName = "uploadFrame_" + Math.floor(Math.random() * 1000);
也可以用一个递增的计算器来代替随机数。
接着创建iframe,本以为用document.createElement("iframe")创建再设置它的name属性就行了。
却发现这样设置的name在ie居然不认(有说name是只读属性),还好在网上找到一个方法:“IE 创建元素,还有一个特点,就是可以连同属性一同创建”。
例如我想给动态创建的iframe设置name,可以这样:
document.createElement("<iframe name=\"" + this._FrameName + "\">")
不过这个方式在ff会报错:
uncaught exception: String contains an invalid character (NS_ERROR_DOM_INVALID_CHARACTER_ERR)
估计是用createElement时不能带name,标准应该也是这样,所以兼容的方式这样写:

Code
var oFrame = isIE ? document.createElement("<iframe name=\"" + this._FrameName + "\">") : document.createElement("iframe");
//为ff设置name
oFrame.name = this._FrameName;
oFrame.style.display = "none";
关于这方面更详细的内容请看这里。
创建完还需要插入到body中,一般的做法是使用document.body.appendChild,但在ie中会有“已终止操作”错误,可以用下面这段代码测试:

Code
<body>
<div>
<script>
document.body.appendChild(document.createElement("div"));
</script>
</div>
</body>
网上找到一个解析:“原来FF下的实现机制是当页面还没有完全读取完时body元素就已经存在了,而IE只有页面完全读取结束body元素才会存在,所以在页面中插入上面这条语句在IE下就会出现错误”。
我在web开发未解之谜中也提到了这个现象,我这里使用了insertBefore代替:
document.body.insertBefore(oFrame, document.body.childNodes[0]);
在服务器端文件传送完(或失败)之后,怎么通知客户端呢?
这里说说我的方法,首先我在客户端定义一个函数:
function Finish(msg){ alert(msg); location.href = location.href; }
很简单,就是显示提示并重新加载页面(如果使用reload会导致ff中iframe重复加载数据)。
那服务器端如何通知客户端的问题,就是iframe如何跟主页面交互。
答案是通过window.parent或window.top,在iframe中parent和top属性“分别返回立即父窗口和最上层的祖先窗口”。
例如我在服务器端处理完数据之后会输出:
context.Response.Write("<script>window.parent.Finish('" + _msg + "');</script>");
就会执行主页面的Finish函数了。
【多文件上传】
对于多文件上传,这里的目的是如何做到163网盘那样,只用一个file控件就实现多文件上传。
这里参考了163网盘的思路,下面说说如何实现:
首先必须有一个文件空间(我自己定的名字),例如程序中的"idFile"对象,这个空间不需要内容甚至一个div就可以,主要是用来存放file控件,程序中Folder属性就是这个文件空间对象。
ps:这里的要求是把file控件都控制在文件空间里,即使不是单file控件的情况。
再说说Files属性,这个属性放的是file控件集合,方便获取file控件,在下面“文件列表”就会用到。
处理这些file控件的程序主要在Ini函数中:
首先是处理文件空间中的file控件:

Code
this.Files = [];
//整理文件空间,把有值的file放入文件集合
Each(this.Folder.getElementsByTagName("input"), Bind(this, function(o){
if(o.type == "file"){ o.value && this.Files.push(o); this.onIniFile(o); }
}))
可以看到这里主要是把file控件放入到Files中,并执行附加函数onIniFile,我是这样定义这个函数的:
onIniFile: function(file){ file.value ? file.style.display = "none" : this.Folder.removeChild(file); }
这里为了实现单file控件,把原来有值的file都隐藏了,还有那个“单file控件”呢?
别急,接着就在文件空间插入一个新的file控件:

Code
var file = document.createElement("input");
file.name = this.FileName; file.type = "file"; file.onchange = Bind(this, function(){ this.Check(file); this.Ini(); });
this.Folder.appendChild(file);
可以看到file控件的name是FileName属性的值,默认是空的,如果服务器端需要这个name的话就可以设置。
这里可以看到每个file控件都有onchange来执行检测函数Check,这样每次选择文件后都会用Check检测一次,这里说说这个Check函数:

Code
//检测变量
var bCheck = true;
//进行空值、文件数、后缀名、同值检测
if(!file.value){
bCheck = false; this.onEmpty();
} else if(this.Limit && this.Files.length >= this.Limit){
bCheck = false; this.onLimite();
} else if(!!this.ExtIn.length && !RegExp("\.(" + this.ExtIn.join("|") + ")$", "i").test(file.value)){
//检测是否允许后缀名
bCheck = false; this.onNotExtIn();
} else if(!!this.ExtOut.length && RegExp("\.(" + this.ExtOut.join("|") + ")$", "i").test(file.value)) {
//检测是否禁止后缀名
bCheck = false; this.onExtOut();
} else if(!!this.Distinct) {
Each(this.Files, function(o){ if(o.value == file.value){ bCheck = false; } })
if(!bCheck){ this.onSame(); }
}
里面有一个检测变量bCheck,然后进行空值、文件数限制、后缀名、相同文件的检测,当其中一个步骤不通过bCheck就会设为false,一个常用的检测结构。
这里说说检测后缀名,由于js不能像后台那样获取文件的文件类型,所以只能根据后缀名来判断,例如用正则判断:
/\.(jpg|gif)$/i.test(file.value)
这样判断显然是不够的,所以如果要做文件类型判断的话一定要在后台用ContentType再判断一次。
最后如果没有通过检测就会执行onFail函数:
!bCheck && this.onFail(file);
我在onFail函数中设定了移除没有通过检测的file控件:
onFail: function(file){ this.Folder.removeChild(file); }
这样就基本实现(正确的说是模拟)了单file控件上传多个文件的效果了。
【文件列表】
在上面的Ini函数中,最后执行了一个附加函数onIni,这个函数是用户自己定义的,我就在这个函数中添加文件列表。
在之前先说说添加文件列表的函数AddList,这个函数是用来把file控件的值列在一个table里面。
函数的参数是一个二维数组,其中第一维是行(tr),第二维是列(td)。
首先获取列表对象FileList,再定义一个文档碎片oFragment来操作dom:
var FileList = $("idFileList"), oFragment = document.createDocumentFragment();
然后用两个Each把二维数组插入到文档碎片中:

Code
Each(rows, function(cells){
var row = document.createElement("tr");
Each(cells, function(o){
var cell = document.createElement("td");
if(typeof o == "string"){ cell.innerHTML = o; }else{ cell.appendChild(o); }
row.appendChild(cell);
});
oFragment.appendChild(row);
})
其中用了一个判断if(typeof o == "string"),如果是文本就直接用innerHTML插入td,如果不是文本(这里不是文本就是一个对象)就用appendChild插入到td。
当数据都插入到文档碎片,就准备把文档碎片插入到FileList中,不过还有一个步骤就是清空FileList中原有的数据。
本来把innerHTML设为空来清空FileList会更有效率,但ie的table中只有td支持innerHTML,所以只好用removeChild来清空:
while(FileList.hasChildNodes()){ FileList.removeChild(FileList.firstChild); }
之后就可以把文档碎片插入了:
FileList.appendChild(oFragment);
继续看onIni函数,现在只需要把要显示的数据组成一个二维数组,再用AddList就能显示文件列表了,这时存放file控件集合的Files属性就大有用处了。
首先定义一个放显示数据的数组:
var arrRows = [];
然后根据Files对这个数组赋值:

Code
if(this.Files.length){
var oThis = this;
Each(this.Files, function(o){
var a = document.createElement("a"); a.innerHTML = "取消"; a.href = "javascript:void(0);";
a.onclick = function(){ oThis.Delete(o); return false; };
arrRows.push([o.value, a]);
});
} else { arrRows.push(["<font color='gray'>没有添加文件</font>", " "]); }
AddRow(arrRows);
当Files没有控件时只是输出“没有添加文件”,有控件时就会把每个file控件的要显示数据放到一个数组中,可以看到这个数组其实就是td内容的集合,接着把这个数组加入到arrRows中形成二维数组,最后把得到的arrRows给AddRow函数显示数据就行了。
为了能取消指定的file控件,这里插入了一个a来触发删除函数Delete,这里也有一个技巧,这里把href设为"javascript:void(0);",并在onclick中返回false,这样能最大程度的实现仅仅执行js而不去跳转。
在表单提交时也要重新显示文件列表,表单提交后就不允许删除文件了,只显示文件路径就行了:

Code
$("idBtnupload").onclick = function(){
//显示文件列表
var arrRows = [];
Each(fu.Files, function(o){ arrRows.push([o.value, " "]); });
AddList(arrRows);
fu.Folder.style.display = "none";
$("idProcess").style.display = "";
$("idMsg").innerHTML = "正在添加文件到您的网盘中,请稍候……<br />有可能因为网络问题,出现程序长时间无响应,请点击“<a href='?'><font color='red'>取消</font></a>”重新上传文件";
fu.Form.submit();
}
说到表单提交要注意一个问题,就是表单是不能嵌套的,最好是把表单放到服务器表单之外,没有办法才使用服务器表单作为提交表单(由于程序会修改提交表单的属性,所以尽量不要这样使用)。
这样文件列表就完成了,有兴趣的话也可以自己封装一下这个功能。
【file样式】
到此,程序的功能都已经实现了,但在163网盘中还有一个特别的地方,就是file控件的样式。
如果有用过163网盘上传文件,就知道那个file控件就像一个按钮,但功能确实是一个file控件。
但当自己尝试修改file控件的样式时,发现单单设置file控件的样式并不能实现想要的效果。
于是我想了另一个办法,用一个button来模拟,结果发现也不行,用js根本操作不了file控件,应该是考虑到安全问题吧。
最后是参考了163网盘和muxrwc模拟126附件添加的效果,总结了这个方法:
1.指定用一个容器(例如程序中的idFile)。
容器最好指定高和宽,并且overflow为hidden,不是块级元素的最好设display为block(为了高和宽的正确呈现);
2.在容器里放一个file控件,并设置样式,使能触发弹出选择文件框的部分覆盖整个容器,并设置成全透明。
容器指定准确的高和宽就是为了能通过file控件中不多的能设置的样式来覆盖整个容器;
3.现在已经把容器模拟成file控件了,可以直接设置容器的样式来模拟设置file控件的样式了。
在程序中主要用file控件的margin-left和font-size来实现覆盖整个容器:

Code
a.files input {
margin-left:-350px;
font-size:30px;
cursor:pointer;
filter:alpha(opacity=0);
opacity:0;
}
至于容器,我使用了有伪类hover的a元素(虽然CSS2中hover可以应用于任何对象,但ie6不支持)。
这里用了一个常用的小技巧,就是用一张图片作为背景通过在hover时修改background-position来实现两张图片的效果:

Code
a.files {
width:90px;
height:30px;
overflow:hidden;
display:block;
border:1px solid #BEBEBE;
background:url(img/fu_btn.gif) left top no-repeat;
text-decoration:none;
}
a.files:hover {
background-color:#FFFFEE;
background-position:0 -30px;
}
在点击这个a时后会出现一个虚线框,在这里显然不太美观,可以把outline设为none来去掉,可是ie又不支持,在网上找到一个方法ie可以把hideFocus设为true来隐藏聚焦(即不显示这个虚线框,hideFocus可以在js或html中设置,也可以通过expression放到css中:

Code
a.files, a.files input {
outline:none;/*ff* /
hide-focus:expression(this.hideFocus=true);/*ie* /
}
这样完全模拟了163网盘的效果了。
【后台】
前台基本完成了,就到后台啦。后台的功能很简单,就是处理传递过来的文件数据。
这里像js + .Net 图片切割系统那样使用ashx文件处理IHttpHandler发送过来的数据。
程序很简单,就直接贴代码了:

Code
int iTotal = context.Request.Files.Count;
if (iTotal == 0)
{
_msg = "没有数据";
}
else
{
int iCount = 0;
for (int i = 0; i < iTotal; i++)
{
HttpPostedFile file = context.Request.Files[i];
if (file.ContentLength > 0 || !string.IsNullOrEmpty(file.FileName))
{
//保存文件
file.SaveAs(System.Web.HttpContext.Current.Server.MapPath("./file/" + Path.GetFileName(file.FileName)));
//这里可以根据实际设置其他限制
if (++iCount > UploadFileLimit)
{
_msg = "超过上传限制:" + UploadFileLimit;
break;
}
}
}
}
这里只检测了有无文件和文件数限制,其他检测如文件大小等可以自己扩展,应该不难。
处理完数据之后就通知客户端:
context.Response.Write("<script>window.parent.Finish('" + _msg + "');</script>");
这个在上面iframe的内容中已经说明了。
使用说明
基本使用很简单,实例化一个file对象,其中参数分别是form对象,文件空间对象:
new FileUpload("uploadForm", "idFile")
这样就实现了一个简单的无刷新上传文件表单。
还可以使用这几个属性:
Form//表单
Folder//文件控件存放空间
Files//文件集合
更多的功能可以选择设置这些属性:
属性名:默认值//说明
FileName:"",//文件上传控件的name,配合后台使用
FrameName:"",//iframe的name,要自定义iframe的话这里设置name
onIniFile:function(){},//整理文件时执行(其中参数是file对象)
onEmpty:function(){},//文件空值时执行
Limit:0,//文件数限制,0为不限制
onLimite:function(){},//超过文件数限制时执行
Distinct:true,//是否不允许相同文件
onSame:function(){},//有相同文件时执行
ExtIn:[],//允许后缀名
onNotExtIn:function(){},//不是允许后缀名时执行
ExtOut:[],//禁止后缀名,当设置了ExtIn则ExtOut无效
onExtOut:function(){},//是禁止后缀名时执行
onFail:function(){},//文件不通过检测时执行(其中参数是file对象)
onIni:function(){}//重置时执行
使用方法可以参考实例。
程序中提供了下面几个方法:
Ini 整理空间
Check 检测file对象
Delete 删除指定file
Clear 删除全部file
完整程序
样式设置

Code
.fu_list {
width:600px;
background:#ebebeb;
font-size:12px;
}
.fu_list td {
padding:5px;
line-height:20px;
background-color:#fff;
}
.fu_list table {
width:100%;
border:1px solid #ebebeb;
}
.fu_list thead td {
background-color:#f4f4f4;
}
.fu_list b {
font-size:14px;
}
/*file容器样式*/
a.files {
width:90px;
height:30px;
overflow:hidden;
display:block;
border:1px solid #BEBEBE;
background:url(img/fu_btn.gif) left top no-repeat;
text-decoration:none;
}
a.files:hover {
background-color:#FFFFEE;
background-position:0 -30px;
}
/*file设为透明,并覆盖整个触发面*/
a.files input {
margin-left:-350px;
font-size:30px;
cursor:pointer;
filter:alpha(opacity=0);
opacity:0;
}
/*取消点击时的虚线框*/
a.files, a.files input {
outline:none;/*ff*/
hide-focus:expression(this.hideFocus=true);/*ie*/
}
html代码

Code
<form id="uploadForm" action="File.ashx">
<table border="0" cellspacing="1" class="fu_list">
<thead>
<tr>
<td colspan="2"><b>上传文件</b></td>
</tr>
</thead>
<tbody>
<tr>
<td align="right" width="15%" style="line-height:35px;">添加文件:</td>
<td><a href="javascript:void(0);" class="files" id="idFile"></a> <img id="idProcess" style="display:none;" src="img/loading.gif" /></td>
</tr>
<tr>
<td colspan="2"><table border="0" cellspacing="0">
<thead>
<tr>
<td>文件路径</td>
<td width="100"></td>
</tr>
</thead>
<tbody id="idFileList">
</tbody>
</table></td>
</tr>
<tr>
<td colspan="2" style="color:gray">温馨提示:最多可同时上传 <b id="idLimit"></b> 个文件,只允许上传 <b id="idExt"></b> 文件。 </td>
</tr>
<tr>
<td colspan="2" align="center" id="idMsg"><input type="button" value="开始上传" id="idBtnupload" disabled="disabled" />
<input type="button" value="全部取消" id="idBtndel" disabled="disabled" />
</td>
</tr>
</tbody>
</table>
</form>
程序代码

Code
var isIE = (document.all) ? true : false;
var $ = function (id) {
return "string" == typeof id ? document.getElementById(id) : id;
};
var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}
var Extend = function(destination, source) {
for (var property in source) {
destination[property] = source[property];
}
}
var Bind = function(object, fun) {
return function() {
return fun.apply(object, arguments);
}
}
var Each = function(list, fun){
for (var i = 0, len = list.length; i < len; i++) { fun(list[i], i); }
};
//
var FileUpload = Class.create();
FileUpload.prototype = {
//表单对象,文件控件存放空间
initialize: function(form, folder, options) {
this.Form = $(form);//表单
this.Folder = $(folder);//文件控件存放空间
this.Files = [];//文件集合
this.SetOptions(options);
this.FileName = this.options.FileName;
this._FrameName = this.options.FrameName;
this.Limit = this.options.Limit;
this.Distinct = !!this.options.Distinct;
this.ExtIn = this.options.ExtIn;
this.ExtOut = this.options.ExtOut;
this.onIniFile = this.options.onIniFile;
this.onEmpty = this.options.onEmpty;
this.onNotExtIn = this.options.onNotExtIn;
this.onExtOut = this.options.onExtOut;
this.onLimite = this.options.onLimite;
this.onSame = this.options.onSame;
this.onFail = this.options.onFail;
this.onIni = this.options.onIni;
if(!this._FrameName){
//为每个实例创建不同的iframe
this._FrameName = "uploadFrame_" + Math.floor(Math.random() * 1000);
//ie不能修改iframe的name
var oFrame = isIE ? document.createElement("<iframe name=\"" + this._FrameName + "\">") : document.createElement("iframe");
//为ff设置name
oFrame.name = this._FrameName;
oFrame.style.display = "none";
//在ie文档未加载完用appendChild会报错
document.body.insertBefore(oFrame, document.body.childNodes[0]);
}
//设置form属性,关键是target要指向iframe
this.Form.target = this._FrameName;
this.Form.method = "post";
//注意ie的form没有enctype属性,要用encoding
this.Form.encoding = "multipart/form-data";
//整理一次
this.Ini();
},
//设置默认属性
SetOptions: function(options) {
this.options = {//默认值
FileName: "",//文件上传控件的name,配合后台使用
FrameName: "",//iframe的name,要自定义iframe的话这里设置name
onIniFile: function(){},//整理文件时执行(其中参数是file对象)
onEmpty: function(){},//文件空值时执行
Limit: 0,//文件数限制,0为不限制
onLimite: function(){},//超过文件数限制时执行
Distinct: true,//是否不允许相同文件
onSame: function(){},//有相同文件时执行
ExtIn: [],//允许后缀名
onNotExtIn: function(){},//不是允许后缀名时执行
ExtOut: [],//禁止后缀名,当设置了ExtIn则ExtOut无效
onExtOut: function(){},//是禁止后缀名时执行
onFail: function(){},//文件不通过检测时执行(其中参数是file对象)
onIni: function(){}//重置时执行
};
Extend(this.options, options || {});
},
//整理空间
Ini: function() {
//整理文件集合
this.Files = [];
//整理文件空间,把有值的file放入文件集合
Each(this.Folder.getElementsByTagName("input"), Bind(this, function(o){
if(o.type == "file"){ o.value && this.Files.push(o); this.onIniFile(o); }
}))
//插入一个新的file
var file = document.createElement("input");
file.name = this.FileName; file.type = "file"; file.onchange = Bind(this, function(){ this.Check(file); this.Ini(); });
this.Folder.appendChild(file);
//执行附加程序
this.onIni();
},
//检测file对象
Check: function(file) {
//检测变量
var bCheck = true;
//空值、文件数限制、后缀名、相同文件检测
if(!file.value){
bCheck = false; this.onEmpty();
} else if(this.Limit && this.Files.length >= this.Limit){
bCheck = false; this.onLimite();
} else if(!!this.ExtIn.length && !RegExp("\.(" + this.ExtIn.join("|") + ")$", "i").test(file.value)){
//检测是否允许后缀名
bCheck = false; this.onNotExtIn();
} else if(!!this.ExtOut.length && RegExp("\.(" + this.ExtOut.join("|") + ")$", "i").test(file.value)) {
//检测是否禁止后缀名
bCheck = false; this.onExtOut();
} else if(!!this.Distinct) {
Each(this.Files, function(o){ if(o.value == file.value){ bCheck = false; } })
if(!bCheck){ this.onSame(); }
}
//没有通过检测
!bCheck && this.onFail(file);
},
//删除指定file
Delete: function(file) {
//移除指定file
this.Folder.removeChild(file); this.Ini();
},
//删除全部file
Clear: function() {
//清空文件空间
Each(this.Files, Bind(this, function(o){ this.Folder.removeChild(o); })); this.Ini();
}
}
测试代码

Code
var fu = new FileUpload("uploadForm", "idFile", { Limit: 3, ExtIn: ["jpg", "gif"],
onIniFile: function(file){ file.value ? file.style.display = "none" : this.Folder.removeChild(file); },
onEmpty: function(){ alert("请选择一个文件"); },
onLimite: function(){ alert("超过上传限制"); },
onSame: function(){ alert("已经有相同文件"); },
onNotExtIn: function(){ alert("只允许上传" + this.ExtIn.join(",") + "文件"); },
onFail: function(file){ this.Folder.removeChild(file); },
onIni: function(){
//显示文件列表
var arrRows = [];
if(this.Files.length){
var oThis = this;
Each(this.Files, function(o){
var a = document.createElement("a"); a.innerHTML = "取消"; a.href = "javascript:void(0);";
a.onclick = function(){ oThis.Delete(o); return false; };
arrRows.push([o.value, a]);
});
} else { arrRows.push(["<font color='gray'>没有添加文件</font>", " "]); }
AddList(arrRows);
//设置按钮
$("idBtnupload").disabled = $("idBtndel").disabled = this.Files.length <= 0;
}
});
$("idBtnupload").onclick = function(){
//显示文件列表
var arrRows = [];
Each(fu.Files, function(o){ arrRows.push([o.value, " "]); });
AddList(arrRows);
fu.Folder.style.display = "none";
$("idProcess").style.display = "";
$("idMsg").innerHTML = "正在添加文件到您的网盘中,请稍候……<br />有可能因为网络问题,出现程序长时间无响应,请点击“<a href='?'><font color='red'>取消</font></a>”重新上传文件";
fu.Form.submit();
}
//用来添加文件列表的函数
function AddList(rows){
//根据数组来添加列表
var FileList = $("idFileList"), oFragment = document.createDocumentFragment();
//用文档碎片保存列表
Each(rows, function(cells){
var row = document.createElement("tr");
Each(cells, function(o){
var cell = document.createElement("td");
if(typeof o == "string"){ cell.innerHTML = o; }else{ cell.appendChild(o); }
row.appendChild(cell);
});
oFragment.appendChild(row);
})
//ie的table不支持innerHTML所以这样清空table
while(FileList.hasChildNodes()){ FileList.removeChild(FileList.firstChild); }
FileList.appendChild(oFragment);
}
$("idLimit").innerHTML = fu.Limit;
$("idExt").innerHTML = fu.ExtIn.join(",");
$("idBtndel").onclick = function(){ fu.Clear(); }
//在后台通过window.parent来访问主页面的函数
function Finish(msg){ alert(msg); location.href = location.href; }
【asp版本补充】
由于很多人问我asp版本的后台该如何写,所以决定写一个给大家。
这里我用了化境HTTP上传程序2.1版(应该是最新版了)的无组件上传类,但用的时候发现几个问题(不知是我不会用还是asp本身的问题):
1,当file控件的name是空时,后台会找不到文件;
2,文件名比较短时(例如我用"f"),后台也找不到文件;
3,当有多个file控件,如果使用相同的name,后台只会保存一个文件;
4,我在上传文件后输出的中文是乱码(有时又正常)。
针对前3条,我加了一个RanName属性,设为true的话会自动生成随机的file控件名,对于第4条,我发现如果字是直接写在文档上就不会乱码,所以我这里把输出的文字都直接写在文档上没有用变量。如果有兄弟知道怎么解决这些问题记得告诉我哦。
下载完整测试代码(.net)
下载完整测试代码(asp)
感谢由csdn网友mengshan1986提供的php和jsp版,klniuer的php修正版:
下载完整测试代码(php)
下载完整测试代码(jsp)
ps:请注意程序中的文件保存路径,很多人的错误都是没有设置好文件保存路径。
posted @ 2008-10-20 08:20
cloudgamer 阅读(21599)
评论(251) 编辑 收藏 所属分类:
AspAsp.netJavascriptweb
发表评论
问下楼主的jsp版本都实现了什么功能,可不可以 就是在本地浏览个文件 然后点击上传,然后就上传到服务器的制定目录上?
#202楼[
楼主]2008-10-28 10:37 |
@loo
可以的啊
这个系统就是实现这个功能
记得修改文件保存路径
为什么我下的。NET没办法上传?
其他的都可以,如ASP的都可以,
#204楼[
楼主]2008-10-29 13:51 |
@学习生
看看路径有没有问题
我写的版本是asp.net 2.0的
还有就是看看是不是机器配置问题,因为其他人都能正常运行的
有机会要多向您学习
如果不嫌弃,可以加我为好友:123347564
ASP版本有BUG,无法自动命名文件名,上传两个(含)以上的文件,提示上传完成,但其实一个文件都没上传。
#207楼[
楼主]2008-10-29 21:12 |
@springhcq
一起学习
不过我不怎么上q,有什么问题可以留言
@wei_wei
我试了一下
没问题啊
你确定你下的是asp版而且没有修改程序?
谢谢LZ的贡献精神;
不过FLASH结合支持多个文件直接选取,
似乎是未来的方向.
#209楼[
楼主]2008-10-30 00:26 |
@conqweal
FLASH跟js不是同一个东西
我觉得没必要把这两个东西进行比较
各自都有自己的发展的
@cloudgamer
关于iframe的创建其实可以不用浏览器检测,可以利用innerHTML属性来完成:
var frameContainer = document.createElement('div'); //创建一个用来放frame的空div
frameContainer.innerHTML = ' <iframe name="frame1" id="frame1" ></frame>';
document.body.appendChild(frameContainer);
上传中文文件名的文件,虽上传成功,单文件名变成乱码了,如何解决!
#213楼[
楼主]2008-11-03 23:00 |
@Freedom~Jun
谢谢支持
@测试566
这个可能是前后台编码不一致的问题,你可以统一一下编码,或者后台重新定一个名也可以
@张荣华
这样就要加一个div
还是不太好
var Each = function(list, fun){
for (var i = 0, len = list.length; i < len; i++) { fun(list[i], i); }
};
朋友 你能不能给我说下这句话的作用,还有一般什么时候用? 有什么好处!麻烦了
#215楼[
楼主]2008-11-04 16:17 |
@Fans
就是对list数组的每个元素作为fun函数的参数执行一次
这样说明白吗
JSP版的读不到文件流呀,在file.jsp中的第一个while循环就退出了,这是怎么回事。
#217楼[
楼主]2008-11-04 17:44 |
@张帅
这个别人测试过应该可以的
因为我不懂jsp也没办法解答你
你好,我想问一下,我运行.NET实例一无法添加文件,一看提示我已存在该文件,可是什么都没有啊。我清除缓存就是重启的没有变化,请问是什么问题,如何解决?
#220楼[
楼主]2008-11-06 14:36 |
@张帅1
呵呵
@bopo
但我这里测试没发现这个问题啊
确定没修改我的程序?
是啊。 没有添加任何代码。
就是直接运行你提供的.NET实例。
对了,我使用的是IE8。
会不会程序在这个环境下有什么问题。
兄弟
var Each = function(list, fun){
for (var i = 0, len = list.length; i < len; i++) { fun(list[i], i); }
};
是不是直接产生闭包了呢?
还有我想知道您博客的预览功能是怎么弄的?
下面这句是判断是否有相同文件吧?
if(o.value == file.value){ bCheck = false; }
我分别alert(o.value),alert(file.value)
看到他们两值却是一样,可是我是添加第一个文件呢。
#225楼[
楼主]2008-11-06 16:08 |
@bopo
ie8的话我就没测试过了
你在这里的效果预览中有没有这个情况
你用ff试试
@Fans
我想你的理解是对的,主要还是想省点代码
至于预览功能,这个blog本身就可以直接贴html代码
一、转了台机方试了试,确实IE8下有问题啊~
二、FF我也试了,文件倒是能上传成功(我到目录下去看以存在),但是界面还是一直停在请等待。
#227楼[
楼主]2008-11-06 17:12 |
@bopo
我用ff3和ie7测试过
没有问题哦
很不错的效果,只是提交页面给程序员的时候,他们说不能跟 JSP 后台连接上,真是有点晕!!多谢!!
#233楼[
楼主]2008-11-11 10:36 |
@谢小妹
@own
@小可66
谢谢支持
@noihsi
jsp应该也行的
详细看例子吧我不怎么懂jsp
在FileUpload.prototype的initialize定义中
this.Distinct = !!this.options.Distinct
为什么前面要打两个!非?
可不可以直接
this.Distinct = this.options.Distinct;代替呢?
#235楼[
楼主]2008-11-14 14:48 |
@poisson123
用!!可以保证返回的是bool值
我发现发上传的都不能重新命名,如果是重名,就只保存最后一个
#238楼[
楼主]2008-11-16 00:29 |
@qingren
写什么进数据库?
@多多大人
不知你是说哪个版本
我这里是直接用原来的文件名作为文件名
你可以在程序中改名再保存文件的
我有个问题,asp.net开发的时候上传一般不会在一个htm页面上,如果一个aspx页套用了模板页,请问怎么将aspx;form里面的action指向'ashx'文件了?!
#240楼[
楼主]2008-11-19 14:13 |
@hier
生成的页面的form肯定有一个id的
你把这个id作为实例化的参数并用js修改它的action
不过之后页面就不能正常提交了
呵呵,楼主东西做的很好,但是更多的应该想想应用方面的要不只能当"花瓶"了。
#242楼[
楼主]2008-11-19 15:02 |
@hier
也不是花瓶啊
这是我们开发的网盘的文件上传部分
asp.net开发也不是不要html啊
而且也可以用其他方法绕过提交的问题
例如插入一个新的form作为提交form,或者把文件上传页面作为iframe插入等等
而且我后台方面很菜,说不定从后台的方向想有好的解决方法(例如弄成一个控件什么的)
我想这里只是一个例子教学,运用时还是自己多思考一下吧
我现在有这样一个需求:
针对每一个附件有一个附件类型字段,比如:工作报告,问题总结等。
这就需要在每添加一个附件时,旁边要有一个下拉菜单来选择附加类型。
但如何将附件和这个附件的类型一起action到提交页面呢??而且附件和类型要一一对应。
#246楼[
楼主]2008-11-23 01:56 |
@fengsky491
@Hunts.C
谢谢支持
@amingo
这个我确实没想到很好的方法
我有一个思路是添加一个file后
根据file的value添加一个类型选择,例如把value作为类型选择的name
这样提交到后台后就能用FileName获取对应的类型数据
不过没有实践过不是是否可行
无奈啊...多文件同时上传.为什么只成功一个..我倒....
#248楼[
楼主]2008-11-25 19:14 |
@木木1983
你说的是哪个版本
jsp的路径那里是不是必须给绝对路径,我给了相对路径怎么不好使!
#252楼[
楼主]2008-12-01 08:23 |
@Daniel_Wu
@dragon_zhang
谢谢支持
你把相对路径转成绝对路径就行了
jsp应该有这样的方法吧
我不太懂jsp
#255楼[
楼主]2008-12-01 15:06 |
@我是小菜
由于安全问题文件大小一般来说在客户端是不能检测得到的,如果是图片的话可以用下面这个方法获取(ie6)
<img id=img1 src="" onload='alert("图片大小"+img1.fileSize/1024+"K");'>
<input type=file name="file1" onchange="img1.src=this.value">
首先感谢楼主的回复,在您没有回复的时候,我自己试了一下这个
var fso = new ActiveXObject('Scripting.FileSystemObject');
var file1 = fso.GetFile(file.value);
file1.Size 就能返回,但这存在安全性的问题,必须在IE的安全里把“没有设为安全的active”那个启用,所以还是楼主高,呵呵,我在现在代码的基础上加了一Length和onLength,向你学习
#257楼[
楼主]2008-12-02 08:23 |
@我是小菜
那个一般客户端都是禁止的
所以一般行不通
楼主写的这个不错。
有一个小地方,“添加文件”按钮问题。IE8中又变成了“浏览”字样。
#260楼[
楼主]2008-12-04 15:31 |
@shawnliu
@醉春风
谢谢支持
这个ie8的问题因为我没有ie8也测试不了
而且ie8正式版都还没出呢
到时再看吧
博主检查一下,貌似现在下的.net完整包中file目录下是空的
#262楼[
楼主]2008-12-09 10:18 |
@克
file目录是用来放上传的文件的
你上传一下就有了
请问楼主怎么添加图片的预览功能呢?
我弄半天没搞懂,看不懂js代码。
根據我的應用場景,我把這個靜態頁面又作為一個iframe嵌入到業務邏輯頁, 我想實現所有與文件上傳處理的東西都在ashx裡面完成,所以需要傳一個業務邏輯頁面的主鍵過來,所以,我在靜態頁面裡面加了一個hidden 通過parent.document.get***byID將我要的主鍵設置進去,爲什麽在ashx裡面用Request.Form無法獲得,相當困惑,請幫忙解答..
#266楼[
楼主]2008-12-18 17:19 |
@@yingwu
谢谢支持
@请帮忙
图片预览主要是要获得路径不过这个在ff和ie7处理比较麻烦你可以找相关资料看看
@PhoenixWong
你说的我不是很明白
iframe是放上传程序吗
那怎么会用parent.document.get***byID来设?
或者你把需求说一下吧
感动!!!答复这么迅猛!!
我在自己的页面中有一个
<iframe id="AttachUpload" src="../FileModule/FileUpload.htm" width="100%" style="border:none; margin:0 0 0 0"></iframe>
用来上传文件, 并我在您的静态页面form里面加了一個
<form id="uploadForm" action="File.ashx" > <input type="hidden" id="RelatedID" />
然后在js的upload函數(我將您在htm中的那個上傳按鈕去掉了,將按鈕時間命名為upload函數, 在防止Iframe的主頁面的前臺驗證完成后用 frames["AttachUpload"].upload(); }触发)中用
document.getElementById("RelatedID").value=parent.document.getElementById("ctl00_ContentPlaceHolder1_txtRequestNo").value; //alert(document.getElementById("RelatedID").value); 將我要的那個RequestNo设置到hidden中,
最後在ashx中 string RelatedID = context.Request.Form["RelatedID"]; 返回一直為null.
#268楼[
楼主]2008-12-18 17:43 |
@PhoenixWong
<input type="hidden" id="RelatedID" />
换成
<input type="hidden" id="RelatedID" name="RelatedID" />
试试
You are totally a giant!!!
果然可以了!! Request.From 難道是通過Names取的么???
万分感谢!!
#270楼[
楼主]2008-12-18 17:56 |
@PhoenixWong
是通过name的
我想你都是用控件很少直接接触html
网上Google了一下如果指定了form的encrytype的话, 数据是通过二进制流出传输的,需要自己在server端自己处理,所以没法这样Request获取.
为何指定name后就可以了?
具体的原因您能说明一下么?
#272楼[
楼主]2008-12-18 18:02 |
@PhoenixWong
传递到服务器的数据确实是二进制流的
但.net已经把这个处理好了所以我们可以直接用Request获取
如果是asp之类的就需要特别处理了
现在觉得自己太寒酸了,以前都是用用户控件实现的. 用戶控件好像不太方便执行我所需要的上传文件处理方法。 我的设想是上传的东西和本页后台不关联(有个主键传过去存DB就可以了)
危机啊……,努力中
#274楼[
楼主]2008-12-18 18:34 |
@PhoenixWong
呵呵
一起努力
博主果然热心人
请问,文件路径的字符串是保存在哪里的?我添加了一个DropDownList1,
想把document.getElementById("DropDownList1").value 添加到上传文件名的后面,根据不同类别放在不同地方,就象这样:
文件路径
c:\aa\a.rar 电影 删除
c:\bb\b.rar 小说 删除
但是我添加了
function AddList(rows){
...
var cell2 = document.createElement("td");
cell2.innerHTML=document.getElementById("DropDownList1").value
row.appendChild(cell2);
oFragment.appendChild(row);
显示出来了,不过,所有文件都是一种选择类型,比如添加a.rar文件是电影,添加b.rar是小说,当选了小说再添加文件b.rar时,a.rar 的类型也变成了小说,DropDownList1的选择项目没有保存
能指导下该怎么做吗?谢谢
#276楼[
楼主]2008-12-19 14:13 |
@emghost
大概明白你说的
你可以这样在Ini中改成这样
Each(this.Folder.getElementsByTagName("input"), Bind(this, function(o){
if(o.type == "file"){ if(!o._temp){o._temp=document.getElementById("DropDownList1").value;}; o.value && this.Files.push(o); this.onIniFile(o); }
}))
这样就给file对象设了一个自定义属性_temp来保存那个值
之后onIni中改这里
arrRows.push([o.value, o._temp, a]);
就能显示这个值了
我也想保存到file对象,没有弄成....水平不够,还的多向博主学习
成了,博主的代码风格真的很好,人也热心,,感谢博主帮助
还有个事情要问下:后台File.ashx如何得到o._temp的值进行判断呢?
单个文件可以用context.Request.Form["DropDownList1"];得到如果多个不同上来context.Request.Form["DropDownList1"];得到的只是最后的值
#279楼[
楼主]2008-12-19 23:47 |
@emghost
说实话这个问题我也想过但没找到很好的方法
等有时间再想想
基本思路是每一个file对应一个hidden
但不知道怎么在后台获取时对应
好像通过name来搞能实现
不过具体没有试过也不清楚了
这个方法可能是唯一的方法了,前台在file后面加一个特殊字符比如#,后台得到后
用split,分开,就可以了
#281楼[
楼主]2008-12-20 08:22 |
@emghost
呵呵
你试试吧
实现了记得发一份给我
cloudgamer,请问我想在页面一打开"文件路径"中就已经存在几个文件在列表中,该怎么处理?
因为我在项目中,想实现第一次只保存,第二次打开时还可以修改的功能.
#283楼[
楼主]2008-12-20 22:08 |
@huanglang
没看明白
第一次只保存是什么意思
第二次又是修改什么
======================================
================博主注意================
======================================
能否将这个论坛的上传效果扣下来....
感觉他的效果比163的还要好
http://bbs.blueidea.com
======================================
======================================
======================================
#285楼[
楼主]2008-12-21 22:59 |
@jser
这个还是你自己来吧
我不是帮人扣代码的
我写好了,可以传递类型值了如下:
Each(this.Files, function(o){
var a = document.createElement("a"); a.innerHTML = "取消"; a.href = "javascript:void(0);";
a.onclick = function(){ oThis.Delete(o); return false; };
arrRows.push([o.value,o._temp, a]);
postRows.push([o._temp]);//我添的代码
});
//下面是我添的代码
var _temptext ="";
for (var i=0;i<postRows.length;i++)
{
_temptext+=postRows[i]+"#";
}
document.getElementById("Text1").value=_temptext
//上面是我添的代码
<input id="Text1" type="hidden" name="Text1" /> 找个地方放这个或者自己定义个
ashx 文件中
添加 string filetypez = context.Request["Text1"];
string[] filetype=filetypez.Split('#');
好了,这样就可以了。其他信息也这样做就好了
#287楼[
楼主]2008-12-22 08:25 |
@emghost
好
有空我研究一下
谢谢
楼主别多心啊
我是想请你帮忙下 我试了多次没搞定哦...
#290楼[
楼主]2008-12-22 20:06 |
@jser
这个还是另请高明吧
扎只相信博主!!!
我每天都要看看你的博客~~~已成了我的生活习惯
#292楼[
楼主]2008-12-23 19:07 |
@jser
谢谢支持
你把代码都拷了应该就行了吧
实在没什么兴趣弄这个
楼上朋友有没有和jquery一块用的,有冲突啊,报$.formvalidator 为空或不是对象
#296楼[
楼主]2008-12-25 16:47 |
@BAsil
@ucetggg
谢谢
@gwazy
我估计是因为我定义了$
你把我程序里的$改成另一个不冲突的试试
http://www.cnblogs.com/cloudgamer/archive/2008/10/20/1314766.html
仿163网盘无刷新文件上传系统
关于这个文章,我想在上传前先检测文件尺寸,比如必须上传文件尺寸为宽度=300,高度=250,这个怎么增加呢?我找到了尺寸判断方法
<script>
function chkimg(Obj){
var tempImg=new Image();
tempImg.onerror=function(){alert('目标类型错误或路径不存在!');Obj.outerHTML=Obj.outerHTML;};
tempImg.onload=function(){if(this.width>90 || this.height>80) {alert('超出规定尺寸!');Obj.outerHTML=Obj.outerHTML;}};
tempImg.src=Obj.value;
}
</script>
<input type=file onpropertychange=chkimg(this)>
怎么将这个判断增加到您的程序中呢?
#299楼[
楼主]2008-12-28 22:38 |
@jser
谢谢支持
@hnsongbiao@gmail.com
请参考check程序
--引用--------------------------------------------------
cloudgamer: @jser
谢谢支持
@hnsongbiao@gmail.com
请参考check程序
--------------------------------------------------------
谢谢回复,IE7下不能判断图片尺寸,有解决办法吗?
#301楼[
楼主]2008-12-29 14:11 |
@hnsongbiao@gmail.com
没有很好的方法
网上好像有用滤镜的方法,你搜索一下吧
上传的时候,如果成功上传会alert一个警告框,如果iTotal = 0;时,不会弹出“没有数据” 这是为什么,我找了好久,都不知道什么原因????????
#303楼[
楼主]2008-12-30 10:20 |
@kw1111111111111111
你说的好像是后台输出的
你从后台代码找吧
public void ProcessRequest(HttpContext context)
{
int iTotal = 0;
try
{
iTotal = context.Request.Files.Count;
}
catch (Exception ex)
{
iTotal = 0;
}
if (iTotal == 0)
{
_msg = "沒有數據或超過文檔大小限制";
}
else
{
int iCount = 0;
for (int i = 0; i < iTotal; i++)
{
HttpPostedFile file = context.Request.Files[i];
if (file.ContentLength > 0 || !string.IsNullOrEmpty(file.FileName))
{
//保存文檔
file.SaveAs(HttpContext.Current.Session["CurrentDir"].ToString() + Path.GetFileName(file.FileName));
//這里可以根據實際設置其它限制
if (++iCount > UploadFileLimit)
{
_msg = "超過上傳限制:" + UploadFileLimit;
break;
}
_msg = "上傳成功";
}
}
}
context.Response.Write("<script type='text/javascript'>window.parent.Finish('" + _msg + "');</script>");
context.Response.End();
}
我把代碼改成這個了,添加了一個
if (iTotal == 0)
{
_msg = "沒有數據或超過文檔大小限制";
}
不會彈出警告框???
#305楼[
楼主]2008-12-30 10:41 |
你不要
try
{
iTotal = context.Request.Files.Count;
}
catch (Exception ex)
{
iTotal = 0;
}
看会不会弹出
再看是哪一个部分有问题吧
if (iTotal == 0)
{
_msg = "沒有數據";
}
原本的這個也彈不出來,如果成功會彈出,其它都彈不出
#307楼[
楼主]2008-12-30 11:09 |
@kw1111111111111111
这样说我也不清楚你的是什么情况
或者你发一份源码email我看看吧
cloudgamer,关于上传前判断图片尺寸,在IE7下的解决办法,我找到了一个,不知道在您的这个程序里能否使用:
上传图片之前判断大小的解决办法(利用IE漏洞)
<script>
var img=null;
function s()
{
if(img)img.removeNode(true);
img=document.createElement("img");
img.style.position="absolute";
img.style.visibility="hidden";
img.attachEvent("onreadystatechange",orsc);
img.attachEvent("onerror",oe);
document.body.insertAdjacentElement("beforeend",img);
img.src=inp.value;
}
function oe()
{
alert("cant load img");
}
function orsc()
{
if(img.readyState!="complete")return false;
alert("图片大小:"+img.offsetWidth+"X"+img.offsetHeight);
alert("图片尺寸:"+img.fileSize);
btn.disabled=false;
}
</script>
<input id=inp type="file">
<br/>
<button onclick="s()">Test</button>
<button id=btn disabled>UpLoad</button>
#310楼[
楼主]2008-12-31 08:42 |
@hnsongbiao@163.com
我测试了
这个在ie6可以
ie7还是不行啊
cloudgamer,您再看看这个可以吗?能否再增加对图片尺寸的判断?
<html>
<head>
<script type="text/javascript">
function getFileSize() {
var path = file.value;
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f = fso.GetFile(path);
alert(f.size);
}
</script>
</head>
<body>
<input type="file" name="file" id="file" value=""></input>
<input type="button" name="GetSize" onclick="getFileSize()" value="获得选择文件大小"></input>
</body>
</html>
#312楼[
楼主]2008-12-31 13:55 |
@hnsongbiao@163.com
这个是用fso
但安全问题一般ie是不会开这个权限的(可以编辑本地文件,你说多危险)
所以这个办法基本没什么用
用.net版的 把htm页面直接放到 <iframe></iframe>中总是提示:“已有相同文件” 倒了。。
如果直接浏览.htm页面也会有这个提示。不知道大家有问题吗??
请教:
我要实现如下样式,请问如何修改?
1.只显示用户名,而不是整个文件路径;
2. 所有添加的文件只在一行显示.
请博主给以解决,不胜感激.
#316楼[
楼主]2009-01-07 16:21 |
@醉春风
貌似不会阿
@Kevan
谢谢支持
@huangzm
1 显示的时候截取一下就行了
2 这个在显示的时候自己设置一下吧
具体请自己研究吧,这些跟程序关系不大
#318楼[
楼主]2009-01-07 21:41 |
@阿斯蒂芬
什么错呢
#321楼[
楼主]2009-01-09 19:28 |
@ξσ Dicky σξ
谢谢支持
@wei1
不知你说的作用是什么
@cloudgamer
下面这些参数变动不起效果。比如说要改上传数量,文件类型等。
实在搞不懂,请赐教。
//设置默认属性
SetOptions: function(options) {
this.options = {//默认值
FileName: "",//文件上传控件的name,配合后台使用
RanName: false,//文件上传的name是否随机名(这个是用于asp的无组件上传)
FrameName: "",//iframe的name,要自定义iframe的话这里设置name
onIniFile: function(){},//整理文件时执行(其中参数是file对象)
onEmpty: function(){},//文件空值时执行
Limit: 2,//文件数限制,0为不限制
onLimite: function(){},//超过文件数限制时执行
Distinct: true,//是否不允许相同文件
onSame: function(){},//有相同文件时执行
ExtIn: ["jpg", "gif", "png"],//允许后缀名
onNotExtIn: function(){},//不是允许后缀名时执行
ExtOut: [],//禁止后缀名,当设置了ExtIn则ExtOut无效
onExtOut: function(){},//是禁止后缀名时执行
onFail: function(){},//文件不通过检测时执行(其中参数是file对象)
onIni: function(){}//重置时执行
};
Extend(this.options, options || {});
},
#323楼[
楼主]2009-01-10 08:22 |
@wei1
这里是默认属性
要修改的话应该在实例化的时候修改
你没看到new的时候
var fu = new FileUpload("uploadForm", "idFile", { Limit: 3, ExtIn: ["jpg", "gif"],
是这里设置了吗
现在FF3 和 IE8都因考虑用户隐私问题,input type = file 的value值,取不到完整的路径,路径过滤到只剩下一个文件名字。这个要怎么处理?
#326楼[
楼主]2009-01-17 16:04 |
@joe1
谢谢支持
@小刚啊
ie8我咩用过不清楚
不过ff3还是有方法的你可以baidu一下
有时间我也会补充上去
楼主你好,我用那个php的代码试了一下,上传的时候总是提示:“正在添加文件到您的网盘中,请稍候……有可能因为网络问题,出现程序长时间无响应,请点击 ,取消...”,想问你一下您可能是那些地方没有设置好啊?先谢谢了。
#328楼[
楼主]2009-02-04 08:19 |
@woshi?
可能是上传失败了
可以找其他人试试
很不错!
我想请教一下,我用的是.net版本的.我如果传个大点的rar文件就是报错:
int iTotal = context.Request.Files.Count;超过了最大请求长度
请问怎么解决,是怎么回事?谢谢了
#330楼[
楼主]2009-02-09 08:49 |
@xuwei
一般服务器都会限制传输文件大小
超过就会出错,你调大一点试试
我将你的代码适当修改后嵌入了我们系统中,但在添加文件按钮按下并选择一个正确格式的文件后,其它的都正确,但file样式没回到可以选择文件的图片,file容器中看不到任何图片,点击页面中任意空白处样式即还原,只有一个隐藏的虚线框,虽然功能没有问题,但界面不符合委托方要求,望解救,谢谢。
#332楼[
楼主]2009-02-10 20:43 |
@friedy
如果你下载的实例中样式没问题的话
就可能是你的页面的问题
或者你给个例子我看
#334楼[
楼主]2009-02-16 10:17 |
@friedy
看哪里
#337楼[
楼主]2009-02-16 13:53 |
@friedy
打不开了
#339楼[
楼主]2009-02-16 14:18 |
@friedy
那不行
工作中
你不能发个页面给我看吗
#341楼[
楼主]2009-02-16 15:44 |
@friedy
没深表歉意那么严重吧,交流交流而已
什么浏览器会有问题
6.0,其它浏览器兼容性没考虑,对日本人就这样,他们不提就没考虑
#344楼[
楼主]2009-02-16 17:00 |
@friedy
建议你还是用file原来的样式算了
谢谢博主提供这么好的工具
js不太懂,请教下博主,我想在form中间加入一个文本框,并且有个判断,文本框必须填写内容并且选择上传了文件,开始上传按钮才生效。
#347楼[
楼主]2009-03-07 11:01 |
@寒@鹏
@kiddik
谢谢支持
有没有文件你可以参考“没有添加文件”那个判断
至于文本框你就加个onchange看有没有内容咯
具体请自己研究吧
@woshi?
php文件大小有限制的php.ini文件有两处,默认是8M和2m需要改为上传的限制,如果文件太大,php会自动拒绝程序是检测不到的。
#350楼[
楼主]2009-03-18 19:51 |
@蒙山
@wanglei555555
谢谢支持!!!
我使用一个弹出窗口弹出FileUpload.htm页,上传完成以后我想得到FileUpload.htm的父窗体请问楼主怎么得到呀?parent得不到,top也得不到请问有什么方法可以解决吗?
谢谢我得到了,搂住做的东西很黄很强大,再次感谢嘿嘿
如果已经上传过同样名字的图片,则会覆盖掉。这个不太好
请问博主,上传含有中文名的文件时会出现乱码是怎么回事?
#356楼[
楼主]2009-03-23 19:55 |
@lee_889988
谢谢支持
@游客123456
这个在实际应用中都会修改文件名,我这里只是给个例子就不用考虑太多了
#357楼[
楼主]2009-03-23 20:04 |
@若
实际应用中文件没有用中文名没留意
下次再修正吧
@cloudgamer
在网上搜了一下,发现在web.config文件中的<System.web>节点下添加<globalization requestEncoding="gb2312" responseEncoding="gb2312"/>配置项可以解决问题。
#359楼[
楼主]2009-03-24 19:48 |
@若
这个我估计是前台是gb编码后台是utf造成的
把前台也改成utf应该就可以了,就不用改web.config
谢谢支持
@cloudgamer
我把charset设置成UTF-8上传依然是乱码。。。
#361楼[
楼主]2009-03-25 08:53 |
@王若
我测试过可以的
不是单单改charset而是把页面属性的编码改为utf
或者你右键直接选utf编码不过这样页面会乱码(文件名不会乱码)
我用了一下,发现一个问题,那就是一个3K的图片上传却需要很长的时间,大概需要20-30秒,实际上文件很快的就上传成功,但是返回结果却需要很久。不知道博主自己试过没有,是不是也有这样的问题。
#364楼[
楼主]2009-03-27 17:44 |
@依依园地
那是你第一次运行的时候吧
运行之后再试试
#366楼[
楼主]2009-03-28 17:59 |
@3123456413231320
可以吧
什么情况下不行
上传文件有数量限制吗?我把html的限制改成一百,后台File.ashx的限制取消了.但是上传5个文件,就一点反应也没有了,用的是.net版的
#368楼[
楼主]2009-04-02 13:50 |
@beckfun
这个一般是服务器的上传限制
你可以看看服务器设置
楼主你好,感谢你这么好的控件,功能也很好,能支持FF,但是我在用苹果浏览器safari的时候发现总是显示没有上传数据。如果再兼容苹果的浏览器safari就完美了。
#370楼[
楼主]2009-04-14 10:22 |
@Kyle.chen
有空看看safari
我都没用过呢
楼主,我是新手,用的是php版。请问应该如何使程序允许上传.html文件和.php文件呢?务必指教一下,急需解决这个问题。
#372楼[
楼主]2009-04-19 01:05 |
@Boating
修改这里
ExtIn: ["jpg", "gif"],
再请教一下楼主,我想让程序在上传文件后以客户端原文件名命名,该怎么修改?
我尝试过使$t=$f_name,又修改了$f_name=$_FILES[$f_input]['name'][$key]; 虽然上传后的确保存了原文件名,但在后面却又多加了一个扩展名。如原来是“01.jpg”,上传后就变成了“01.jpg.jpg”。请问楼主,如何才能解决这一问题?
#374楼[
楼主]2009-04-20 08:34 |
@Boating
这个是后台的处理问题吧
我不懂php的,不好意思了
逐一看完你的博文, 很多值得学习的地方。 希望有机会可以共同探讨学习。
#376楼[
楼主]2009-05-13 22:24 |
@your fans
呵呵
欢迎交流
LZ做的很好,为什么我发布到服务器 ,就不能上传了?一直在走进度条?难道是服务器设置问题?
#380楼[
楼主]2009-05-21 10:55 |
@Hand
@ddda
谢谢支持
@hhe
你先本地试试
如果正常的话就是服务器设置问题了
可能是上传数据限制之类的
--引用--------------------------------------------------
Kyle.chen: 楼主你好,感谢你这么好的控件,功能也很好,能支持FF,但是我在用苹果浏览器safari的时候发现总是显示没有上传数据。如果再兼容苹果的浏览器safari就完美了。
--------------------------------------------------------
强大的楼主 我在safari 和chrome 都出现了这个问题,请问有什么好办法解决一下,谢谢!
#382楼[
楼主]2009-05-28 16:56 |
@chris_thanks
我测试了一下
这个是.net的问题哦
用asp版本就没有问题
数据确实是传过去了
但context.Request.Files却取不到数据
估计ms没有做好兼容
这是后台问题前台也没办法
--引用--------------------------------------------------
王若: @cloudgamer
我把charset设置成UTF-8上传依然是乱码。。。
--------------------------------------------------------
#384楼[
楼主]2009-05-30 18:56 |
@破解
这个问题已经解决了,请重新下载实例
可惜没有上传进度,上传文件不知道上传具体情况。。。
#386楼[
楼主]2009-06-03 08:25 |
@猫狼
上传进度关键是后台
前台最多只是根据后台反映出来,前台本身是获取不了的
楼主:你好
在点击添加文件时,弹出个选择文件的对话框是单选的,我想实现上传图片一次在多选。。。
请问怎么搞啊,我看了您的代码没有看到得到对话框中文件在本地的地址的处理。。
#389楼[
楼主]2009-06-05 09:35 |
@SoftWareBoy
这个用js做不到的
改用flash吧
楼主的代码知识好强大啊!刚刚试了一下,发现上载很快。
不过如果我要显示出已上载的文件供他人下载或修改的话,应该加上哪些代码呢?请楼主不吝赐教,谢谢!:)
#391楼[
楼主]2009-06-16 16:32 |
@ecchua79
你说的跟这个上传文件关系不大了
为什么 JSP的代码上传有点问题?
将这两个页放在其它项目中上传不了。单独新建项目可以。
而且好像不兼容FF.
.NET的代码都测试OK
#393楼[
楼主]2009-06-25 16:18 |
@cwmwss
这个就不清楚了
我jsp一点也不懂的
@cloudgamer
放在其它项目的时候,好像找不到action="file.jsp"这个jsp文件。
单独的就执行了。
难道我的tomcat有问题。。。
#395楼[
楼主]2009-06-25 16:59 |
@cwmwss
这个你问问其他人吧
如果真的有问题最好也帮我修正一下
我自己也不会弄
博主你好,我想在上传文件的同时把文件名,文件大小的数据保存到数据库里面应该在什么位置添加数据库代码???请赐教!
#397楼[
楼主]2009-07-01 13:58 |
@daleho
如果是原文件的文件名和文件大小都可以在后台通过文件数据获取啊
感谢楼主的回复这么快,不过我是在你那个ashx文件内的文件上传代码上面加的,结果并没有添加到数据库!
#399楼[
楼主]2009-07-01 14:35 |
@daleho
我那个本身就没有数据库功能,这个你自己扩展吧
跟上传本身也关系不大
我把数据库建立好的,在file.ashx文件里面,利用file.FileName这个得到文件名等信息,在file.SaveAs上面加入了数据添加命令,是不是这样不对?
还是必须要重新建立一个什么东东!我是新手,对asp.net不是很熟悉!
#401楼[
楼主]
2009-07-01 15:07 |
@daleho
那这个你要问熟悉的人咯
你这个是后台问题不是前台问题了