之前一直以为Response.Redirect (“default1.aspx”)的运行原理是这样的
但经过断点测试发现不是,当程序执行到Response.Redirect (“default1.aspx”);时 下边会跳转到default1.aspx下的Page_Load()方法中。也就是说2,3根本没有运行,只有1跟4,浏览器在根据4返回的状态码来在前台地址栏显示出不同的url,说到这里了 咱们就反编译一把Response.Redirect看看里面的具体实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
internalvoidRedirect(
string
url,
bool
endResponse,
bool
permanent)
{
if
(url ==
null
)
{
thrownewArgumentNullException(
"url"
);
}
if
(url.IndexOf(
'\n'
) >= 0)
{
thrownewArgumentException(SR.GetString(
"Cannot_redirect_to_newline"
));
}
if
(
this
._headersWritten)
{
thrownewHttpException(SR.GetString(
"Cannot_redirect_after_headers_sent"
));
}
Pagepage =
this
._context.HandlerasPage;
if
((page !=
null
) && page.IsCallback)
{
thrownewApplicationException(SR.GetString(
"Redirect_not_allowed_in_callback"
));
}
url =
this
.ApplyRedirectQueryStringIfRequired(url);
url =
this
.ApplyAppPathModifier(url);
url =
this
.ConvertToFullyQualifiedRedirectUrlIfRequired(url);
url =
this
.UrlEncodeRedirect(url);
this
.Clear();
if
(((page !=
null
) && page.IsPostBack) && (page.SmartNavigation && (
this
.Request[
"__smartNavPostBack"
] ==
"true"
)))
{
this
.Write(
"<BODY><ASP_SMARTNAV_RDIR url=\""
);
this
.Write(HttpUtility.HtmlEncode(url));
this
.Write(
"\"></ASP_SMARTNAV_RDIR>"
);
this
.Write(
"</BODY>"
);
}
else
{
this
.StatusCode = permanent ? 0x12d : 0x12e;
this
.RedirectLocation = url;
if
(UriUtil.IsSafeScheme(url))
{
url = HttpUtility.HtmlAttributeEncode(url);
}
else
{
url = HttpUtility.HtmlAttributeEncode(HttpUtility.UrlEncode(url));
}
this
.Write(
"<html><head><title>Object moved</title></head><body>\r\n"
);
this
.Write(
"<h2>Object moved to <a href=\""
+ url +
"\">here</a>.</h2>\r\n"
);
this
.Write(
"</body></html>\r\n"
);
}
this
._isRequestBeingRedirected =
true
;
EventHandlerredirecting = Redirecting;
if
(redirecting !=
null
)
{
redirecting(
this
, EventArgs.Empty);
}
if
(endResponse)
{
this
.End();
}
}
|
其中由37,38行的
this
.StatusCode = permanent ? 0x12d : 0x12e;
this
.RedirectLocation = url;
可以看出状态码和跳转地址是在这里赋值的,我邪恶的感觉到扩展IhttpModule可以拦截http状态码,使用js代码段来实现http页面的跳转,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Web;
namespace
ClassLibrary2
{
public
class
Class1 : System.Web.IHttpModule
{
public
void
Init(HttpApplication application)
{
application.PreSendRequestHeaders +=
new
EventHandler(application_PreSendRequestHeaders);
}
private
void
application_PreSendRequestHeaders(
object
sender, EventArgs e)
{
HttpApplication Application = (HttpApplication) sender;
HttpContext context = Application.Context;
if
(context.Response.StatusCode == 302)
{
context.Response.Write(
"<script>window.open(’"
+ context.Response.RedirectLocation +
"’)</script>"
);
context.Response.StatusCode = 200;
}
}
}
}
|
然后再配置一下web.config
1
2
3
4
5
6
7
8
9
10
|
<?
xml
version
=
"1.0"
?>
<
configuration
>
<
system.web
>
<
compilation
debug
=
"true"
/>
<
authentication
mode
=
"Windows"
/>
<
httpModules
>
<
add
name
=
"MyModule"
type
=
"ClassLibrary2.Class1,ClassLibrary2"
></
add
>
</
httpModules
>
</
system.web
>
</
configuration
>
|
本文转自 tongling_zzu 51CTO博客,原文链接:http://blog.51cto.com/tongling/1234188