天天看點

Response.Redirect 原理及實作

但經過斷點測試發現不是,當程式執行到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

<code>internalvoidRedirect(</code><code>string</code> <code>url, </code><code>bool</code> <code>endResponse, </code><code>bool</code> <code>permanent)</code>

<code>{</code>

<code>    </code><code>if</code> <code>(url == </code><code>null</code><code>)</code>

<code>    </code><code>{</code>

<code>        </code><code>thrownewArgumentNullException(</code><code>"url"</code><code>);</code>

<code>    </code><code>}</code>

<code>    </code><code>if</code> <code>(url.IndexOf(</code><code>'\n'</code><code>) &gt;= 0)</code>

<code>        </code><code>thrownewArgumentException(SR.GetString(</code><code>"Cannot_redirect_to_newline"</code><code>));</code>

<code>    </code><code>if</code> <code>(</code><code>this</code><code>._headersWritten)</code>

<code>        </code><code>thrownewHttpException(SR.GetString(</code><code>"Cannot_redirect_after_headers_sent"</code><code>));</code>

<code>    </code><code>Pagepage = </code><code>this</code><code>._context.HandlerasPage;</code>

<code>    </code><code>if</code> <code>((page != </code><code>null</code><code>) &amp;&amp; page.IsCallback)</code>

<code>        </code><code>thrownewApplicationException(SR.GetString(</code><code>"Redirect_not_allowed_in_callback"</code><code>));</code>

<code>    </code><code>url = </code><code>this</code><code>.ApplyRedirectQueryStringIfRequired(url);</code>

<code>    </code><code>url = </code><code>this</code><code>.ApplyAppPathModifier(url);</code>

<code>    </code><code>url = </code><code>this</code><code>.ConvertToFullyQualifiedRedirectUrlIfRequired(url);</code>

<code>    </code><code>url = </code><code>this</code><code>.UrlEncodeRedirect(url);</code>

<code>    </code><code>this</code><code>.Clear();</code>

<code>    </code><code>if</code> <code>(((page != </code><code>null</code><code>) &amp;&amp; page.IsPostBack) &amp;&amp; (page.SmartNavigation &amp;&amp; (</code><code>this</code><code>.Request[</code><code>"__smartNavPostBack"</code><code>] == </code><code>"true"</code><code>)))</code>

<code>        </code><code>this</code><code>.Write(</code><code>"&lt;BODY&gt;&lt;ASP_SMARTNAV_RDIR url=\""</code><code>);</code>

<code>        </code><code>this</code><code>.Write(HttpUtility.HtmlEncode(url));</code>

<code>        </code><code>this</code><code>.Write(</code><code>"\"&gt;&lt;/ASP_SMARTNAV_RDIR&gt;"</code><code>);</code>

<code>        </code><code>this</code><code>.Write(</code><code>"&lt;/BODY&gt;"</code><code>);</code>

<code>    </code><code>else</code>

<code>        </code><code>this</code><code>.StatusCode = permanent ? 0x12d : 0x12e;</code>

<code>        </code><code>this</code><code>.RedirectLocation = url;</code>

<code>        </code><code>if</code> <code>(UriUtil.IsSafeScheme(url))</code>

<code>        </code><code>{</code>

<code>            </code><code>url = HttpUtility.HtmlAttributeEncode(url);</code>

<code>        </code><code>}</code>

<code>        </code><code>else</code>

<code>            </code><code>url = HttpUtility.HtmlAttributeEncode(HttpUtility.UrlEncode(url));</code>

<code>        </code><code>this</code><code>.Write(</code><code>"&lt;html&gt;&lt;head&gt;&lt;title&gt;Object moved&lt;/title&gt;&lt;/head&gt;&lt;body&gt;\r\n"</code><code>);</code>

<code>        </code><code>this</code><code>.Write(</code><code>"&lt;h2&gt;Object moved to &lt;a href=\""</code> <code>+ url + </code><code>"\"&gt;here&lt;/a&gt;.&lt;/h2&gt;\r\n"</code><code>);</code>

<code>        </code><code>this</code><code>.Write(</code><code>"&lt;/body&gt;&lt;/html&gt;\r\n"</code><code>);</code>

<code>    </code><code>this</code><code>._isRequestBeingRedirected = </code><code>true</code><code>;</code>

<code>    </code><code>EventHandlerredirecting = Redirecting;</code>

<code>    </code><code>if</code> <code>(redirecting != </code><code>null</code><code>)</code>

<code>        </code><code>redirecting(</code><code>this</code><code>, EventArgs.Empty);</code>

<code>    </code><code>if</code> <code>(endResponse)</code>

<code>        </code><code>this</code><code>.End();</code>

<code>}</code>

其中由37,38行的

<code>this</code><code>.StatusCode = permanent ? 0x12d : 0x12e;</code>

<code></code><code>this</code><code>.RedirectLocation = url;</code>

可以看出狀态碼和跳轉位址是在這裡指派的,我邪惡的感覺到擴充IhttpModule可以攔截http狀态碼,使用js代碼段來實作http頁面的跳轉,代碼如下:

<code>using</code> <code>System;</code>

<code>using</code> <code>System.Collections.Generic;</code>

<code>using</code> <code>System.Text;</code>

<code>using</code> <code>System.Web;</code>

<code>namespace</code> <code>ClassLibrary2</code>

<code>    </code><code>public</code> <code>class</code> <code>Class1 : System.Web.IHttpModule</code>

<code>        </code><code>public</code> <code>void</code> <code>Init(HttpApplication application)</code>

<code>            </code><code>application.PreSendRequestHeaders += </code><code>new</code> <code>EventHandler(application_PreSendRequestHeaders);</code>

<code>        </code><code>private</code> <code>void</code> <code>application_PreSendRequestHeaders(</code><code>object</code> <code>sender, EventArgs e)</code>

<code>            </code><code>HttpApplication Application = (HttpApplication) sender;</code>

<code>            </code><code>HttpContext context = Application.Context;</code>

<code>            </code><code>if</code> <code>(context.Response.StatusCode == 302)</code>

<code>            </code><code>{</code>

<code>                </code><code>context.Response.Write(</code><code>"&lt;script&gt;window.open(’"</code> <code>+ context.Response.RedirectLocation + </code><code>"’)&lt;/script&gt;"</code><code>);</code>

<code>                </code><code>context.Response.StatusCode = 200;</code>

<code>            </code><code>}</code>

<code>  </code>

然後再配置一下web.config

<code>&lt;?</code><code>xml</code> <code>version</code><code>=</code><code>"1.0"</code><code>?&gt;</code>

<code>  &lt;</code><code>configuration</code><code>&gt;</code>

<code>  &lt;</code><code>system.web</code><code>&gt;</code>

<code>  &lt;</code><code>compilation</code> <code>debug</code><code>=</code><code>"true"</code><code>/&gt;</code>

<code>  &lt;</code><code>authentication</code> <code>mode</code><code>=</code><code>"Windows"</code><code>/&gt;</code>

<code>  &lt;</code><code>httpModules</code><code>&gt;</code>

<code>  &lt;</code><code>add</code> <code>name</code><code>=</code><code>"MyModule"</code> <code>type</code><code>=</code><code>"ClassLibrary2.Class1,ClassLibrary2"</code><code>&gt;&lt;/</code><code>add</code><code>&gt;</code>

<code>  &lt;/</code><code>httpModules</code><code>&gt;</code>

<code>  &lt;/</code><code>system.web</code><code>&gt;</code>

<code>  &lt;/</code><code>configuration</code><code>&gt;</code>

本文轉自 tongling_zzu 51CTO部落格,原文連結:http://blog.51cto.com/tongling/1234188