Response.Redirect 原理及实现
之前一直以为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