(转)客户端验证上传文件大小(兼容IE和火狐)

客户端验证上传文件大小,在IE下面可以很简单,但是需要修改ActiveX安全设置。同时火狐不支持ActiveX。于是这个问题就变得棘手了。解决这个问题的直接思路:1.获得文件路径以后使用AJAX验证文件大小;2.查看浏览器内部属性方法看看到底是否支持读取本地文件大小。

第一种思路:首先获取上传控件的值(这个值就是上传文件在本地的路径),通过AJAX在后台可以轻易的得到文件详细信息,之后再利用回调函数做一些处理工作。这种思路的关键在于--如何得到这个文件路径。稍微有点经验的人都知道,通过上传控件的id.value是得不到真实的文件路径,ie7和 ie8在路径里面加入了fakepath(只能看见盘符、fakepath、文件名)而火狐更狠,直接得到的是文件名。当然上述结论对IE6无效。

于是这个思路还需要好好研究,探索一番发现IE7和IE8获得文件路径还是有方法的:fileupload.select();
var path=document.selection.createRange().text。
这个方法还没有仔细研究,从字面上看似乎是先把控件选择,然后再通过某种方式把选中的值找出来。。。(~~,知道的人顺便告知下)。这下子就只需要搞定火狐了。baidu发现火狐获取路径还很麻烦,涉及到编码问题,找了几个答案都说得不明不白。闲话一段:感觉搜索引擎搜索专业问题都很无能为力,baidu如此,google也如此。不过这也说明了搜索引擎的未来还可以变得更好。无奈之下转向第二种思路:查看各浏览器的内部实现,看看是不是有什么方法或者属性直接读取上传文件的大小。首先在IE8的开发人员工具下断点调试,对fileupload的属性和方法一个个的找,毫无悬念的无果。于是不免叹气,IE7 和IE8都居然对JS访问本地文件做出这么严格的限制,想当然地以为火狐肯定也不行!但是还是不死心,还是找找看。于是拿起FireBug又是一番调试,果然皇天不负有心人,最后终于让哥找到了这个属性: var size=fileupload.files[0].fileSize;

原来火狐居然可以直接读出文件大小,令人惊叹啊!可惜在网络上并没想发现其他人有类似发现或者介绍,于是马上写了此文。于是稍微整理了一下发了个 DEMO,AJAX用的是PageMethods,不会的可以参考我的这篇文章:ASP.NET Ajax 之 Page Methods

页面代码:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="FileUploadTest.aspx.cs" Inherits="FileUploadTest" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>www.liehuo.net</title>
<style type="text/css">
#File1
{
height: 22px;
width: 264px;
}
</style>
<script language="javascript" type="text/javascript">
function disableSave(obj) {
var btnsave = document.getElementById("Button2");
btnsave.disabled = true;
}
function validateFileSize(id,maxsize) {
var btnsave = document.getElementById("Button2");
btnsave.disabled = false;
var filepath = "";
var fileupload = document.getElementById(id);
if (fileupload.value.length < 5) { alert('请选择文件!'); return; }
var agent = window.navigator.userAgent;
if (document.all) {
var isIE7 = agent.indexOf('MSIE 7.0') != -1;
var isIE8 = agent.indexOf('MSIE 8.0') != -1;
//IE7和IE8获得文件路径
if (isIE7 || isIE8) {
fileupload.select();
filepath = document.selection.createRange().text;
}
//IE6获得文件路径
else
{ filepath = file.value; }
PageMethods.ValidateFile(filepath, maxsize, ieCallBack);
}
if (agent.indexOf("Firefox") >= 1) {
if (fileupload.files) {
var size = fileupload.files[0].fileSize;
if (size > parseInt(maxsize)) {
fileupload.parentNode.innerHTML = '<input type="file" name="' + fileupload.name + '" id="' + fileupload.id + '" onchange="disableSave(this);"/> ';
alert("文件超过大小!");
}
else { alert("文件上传成功!"); }
}
}
}
function ieCallBack(response) {
if (response == "invalid") {
var file = document.getElementById('FileUpload1');
file.parentNode.innerHTML = '<input type="file" name="' + file.name + '" id="' + file.id + '" onchange="disableSave(this);"/> ';
alert("文件超过大小!");
}
else { alert("文件上传成功!"); }
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
</asp:ScriptManager>
<div>
<div style="text-align:center">
JavaScript验证客户端上传文件大小
<br />不启用安全设置,兼容IE火狐
<br />
<span> <input id="FileUpload1" type="file" onchange="disableSave(this);" runat="server"/></span>
<input id="Button1" type="button"value="上传文件" onclick="validateFileSize('FileUpload1','102400');"/>
<br />
<asp:Button ID="Button2" runat="server" Text="保存记录"
onclick="Button2_Click" />
<br />
验证文件大小未超过指定值后,给TEXTBOX赋值
<br />
<asp:TextBox ID="TextBox1" runat="server" TextMode="MultiLine" Height="84px" Width="348px"></asp:TextBox>
<br />
设计思路:当用户选择“浏览”将“保存记录”按钮禁用,<br />
只有经过“上传文件”按钮验证以后才能提交记录。<br />
验证不通过则将上传控件的值清空,通过则不作处理。
</div>
</div>
</form>
</body>
</html>

后台代码:代码
using System;
using System.IO;
using System.Web.Services;

public partial class FileUploadTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}

pbotected void Button2_Click(object sender, EventArgs e)
{

TextBox1.Text = "你成功的上传了文件" + FileUpload1.PostedFile.FileName;
}

[WebMethod]

public static string ValidateFile(string filepath, string filezie)

{

var fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);

if (fs.Length > int.Parse(filezie))

return "invalid";

return "valid";

}

}

posted @ 2011-03-08 18:34  半日闲  阅读(2049)  评论(2编辑  收藏  举报