再加上实在是不愿意花时间去写文件上传进度,只得在网上找到了swfupload用flash上传文件的插件,在IE下上传多文件十分顺利,但是在火狐下
却总是报302错误,通过千百度,蓦然回首到谷歌折腾了番,才了解了原因,谨以此篇小计下来,毕竟上传带进度条的功能实在是太常见了,先收
着。
因为SWFUpload是靠Flash进行上传的,Flash在IE下会把当前页面的Cookie发到Upload.aspx,但是Chrome、Firefox下则不会把当前页面的Cookie发到Upload.aspx。因为Session是靠Cookie中保存的SessionId实现的,这样由于当前页面的Cookie不会传递给Flash请求的Upload.aspx,因此请求的文件发送到Upload.ashx就是一个新的Session了,当然这个Session就是没有登录的了。
解决这个问题的思路也很简单,那就是手动把SessionId传递给服务器,再服务器端读出SessionId再加载Session。其实解决问题的办法SWFUpload的Demo中已经给出了,那就是在SWFUpload的构造函数中设置post_params参数:
swfu = new SWFUpload({
// Backend Settings
upload_url: "/Upload.aspx",
post_params: {
"ASPSESSID": "<%=Session.SessionID %>"},
post_params中设定的键值对将会以Form表单的形式传递到Upload.aspx,也就是SWFUpload提供了为请求增加自定义请求参数的接口。
如果网站中还用到了Membership的FormsAuthentication验证,则还需要把AUTHID也按照SessionID的方法进行处理
swfu = new SWFUpload({
// Backend Settings
upload_url: "/Upload.ashx",
post_params: {
"ASPSESSID": "<%=Session.SessionID %>"},
"AUTHID" : "<%=Request.Cookies[FormsAuthentication.FormsCookieName].Value%>",
protected void Application_BeginRequest(object sender, EventArgs e)
{
try
{
string session_param_name = "ASPSESSID";
string session_cookie_name = "ASP.NET_SESSIONID";
if (HttpContext.Current.Request.Form[session_param_name] != null)
{
UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]);
}
else if (HttpContext.Current.Request.QueryString[session_param_name] != null)
{
UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString[session_param_name]);
}
}
catch (Exception)
{
}
try
{
string auth_param_name = "AUTHID";
string auth_cookie_name = FormsAuthentication.FormsCookieName;
if (HttpContext.Current.Request.Form[auth_param_name] != null)
{
UpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]);
}
else if (HttpContext.Current.Request.QueryString[auth_param_name] != null)
{
UpdateCookie(auth_cookie_name, HttpContext.Current.Request.QueryString[auth_param_name]);
}
}
catch (Exception)
{
}
}
void UpdateCookie(string cookie_name, string cookie_value)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
if (cookie == null)
{
HttpCookie cookie1 = new HttpCookie(cookie_name, cookie_value);
Response.Cookies.Add(cookie1);
}
else
{
cookie.Value = cookie_value;
HttpContext.Current.Request.Cookies.Set(cookie);
}
}
原理:当用户请求到达ASP.Net引擎的时候Application_BeginRequest方法首先被调用,在方法中看客户端是否提交上来了ASPSESSID,如果有的话则把ASPSESSID的值写入Cookie(以"ASP.NET_SESSIONID"为Key,因为ASP.Net中SessionId就是保存在"ASP.NET_SESSIONID"为Key的Cookie中的),Application_BeginRequest方法后就可以从Cookie中读取到"ASP.NET_SESSIONID"的值还原出页面的Session了。
如果网站是使用Windows方式验证的,post_params:{
ASPSESSID: "<%=Session.SessionID %>",这样便可,不需要在Application_BeginRequest写任何方法。
相关阅读