词条统计
浏览次数:7940 次
编辑次数:8次 历史版本
最近更新:2013/6/20
创建者:掷鸡蛋者

在上传图片或文件的时候,显示进度条,是非常必要的功能,可以大大提升用户体验。 但悲剧的是,几乎所有主流浏览器都不会显示进度条,google浏览器是个例外所以必须使用其他插件,最最常见的做法是使用flash,wojilu框架从1.6开始,集成了著名的uploadify上传控件,这个控件和其他同类控件相比,使用相对简单。Uploadify 的官方网址是:http://www.uploadify.com/  ,它采用 mit license 授权 ,可免费用于商业目的。


wojilu 1.9 新版的上传控件升级到 uploadify 3.1,内部使用 SWFupload,更加稳定。使用也更加简单。


1)代码和演示

1)基本异步上传演示&代码(使用iframe技术):http://www.wojilu.com/Demo/Upload/FrameUpload.aspx 

2)使用flash上传,显示进度条和速度:http://www.wojilu.com/Demo/Upload/FlashUpload.aspx


2)服务端代码说明


第一,呈现控件的action需要添加:
set( "uploadLink", to( SaveUpload ) ); // 接受上传的网址
set( "sessionId", HttpContext.Current.Session.SessionID ); // sessionId信息
set( "authCookieName", ctx.web.CookieAuthName() ); // cookie验证信息
set( "authCookieValue", ctx.web.CookieAuthValue() ); // cookie验证信息


请注意,这里就是flash上传最关键的部分。
在firefox/chrome等浏览器中,flash无法把当前登录用户的身份信息(比如session的cookie)发送到服务器,所以你必须显式编码,将用户的身份验证cookie(这里的authCookie)和sessionId传入flash,否则服务器端会认为flash没有权限上传。

对于身份验证,在框架教程中,我们谈了两种验证方式:
第一种是session验证:http://www.wojilu.com/Common/Page/33
第二种是cookie验证:http://www.wojilu.com/Common/Page/34

在“我记录网站综合系统”中,用户前台登录用的是cookie验证;用户如果是管理员,要进入后台,还要进而二次验证,这个二次验证则是用的session方式。所以,如果在前台使用flash上传,则只要设置authCookieName和authCookieValue,如果是后台,还需要增加设置sessionId的值给flash控件。

至于你自己开发的系统,请根据验证方式设置:
如果是cookie方式,则设置authCookieName和authCookieValue;
如果是session方式,则设置sessionId;
如果是cookie+session结合方式,则需要像综合系统后台一样,两者都设置。

第二,在 Global.asax 中增加如下代码,它可以根据flash传递过来sessionId判断用户的身份。

void Application_BeginRequest( object sender, EventArgs e ) {

    String sessionId = getSessionId();

    if (sessionId != null) updateCookie( sessionId );

}


String getSessionId() {

    String sessionId = "ASPNET_SESSIONID";

    if (Request.Form[sessionId] != null) return Request.Form[sessionId];

    if (Request.QueryString[sessionId] != null) return Request.QueryString[sessionId];

    return null;

}


void updateCookie( String sessionId ) {

    String cookieName = "ASP.NET_SESSIONID";

    HttpCookie cookie = Request.Cookies.Get( cookieName );

    if (cookie == null) {

        Response.Cookies.Add( new HttpCookie( cookieName, sessionId ) );

    }

    else {

        cookie.Value = sessionId;

        Request.Cookies.Set( cookie );

    }

}



第二部分:保存图片

1)保存图片

如果是保存文件,请用:
Uploader.SaveFile( ctx.GetFileSingle() );

如果是保存图片,请用:
Uploader.SaveImg( ctx.GetFileSingle() );

客户端flash是一次上传一个文件,逐个上传,所以服务器端你只要处理一个文件即可。


2)将上传信息返回到客户端

a)服务器端代码:
Result result = Uploader.SaveImg( ctx.GetFileSingle() );
String picName = result.Info.ToString(); // 获取图片名称
String picUrl = strUtil.Join( sys.Path.Photo, picName ); // 获取图片完整路径
echoText( picUrl ); // 将图片网址返回给客户端


b)客户端写一段js来显示图片信息
"onComplete" : function(event, ID, fileObj, response, data) {
$("#mypic").html( "<img src='"+ response +"' />" );

}

第三部分:配置

在/framework/config/site.config中,你可以设置服务器允许接受的文件类型:
UploadFileTypes : 7z/zip/rar/doc/docx
UploadPicTypes : jpg/gif/png/bmp/jpeg


第一个是支持的文件类型,第二个是支持的图片类型。
另外,默认服务器不支持几百兆的大文件,你必须手动开启,请打开 web.config,修改其中的:
<httpRuntime maxRequestLength="800000" />
将 maxRequestLength 改成你允许的最大上传大小。这里的配置表示800M。

【常见问题】
问题1:如果在客户端即出现“*** file - HTTP Error”类似错误,请依次检查:
1)cookie值是否有效(在网页上右键查看源码,看cookie是否正确赋值)
2)查看log日志,如果文件夹没有写权限,或者上传超过指定大小,会有错误日志发生。


问题2:如何将错误信息反馈到客户端?
1)在服务端获取错误信息
Result result = Uploader.SaveFile( postedFile );
if (result.HasErrors) {
echoText( 封装了 result.ErrorsText 的错误信息 );
return;
}

2)在客户端监测response是否有效,并提供反馈

"onComplete" : function(event, ID, fileObj, response, data) {
if( response==... ) //这里监测是否错误信息

}


更多 uploadify 的参数说明,请查看官方网址:http://www.uploadify.com/