深入解析Django重定向機制

概述

核心是一個基類 HttpResponseRedirectBase,以及兩個具體的子類 HttpResponseRedirect(302 臨時重定向)和 HttpResponsePermanentRedirect(301 永久重定向)。它們都是 HttpResponse 的子類,專門用于告訴客戶端(通常是瀏覽器)跳轉到另一個URL。


class HttpResponseRedirectBase(HttpResponse):allowed_schemes = ['http', 'https', 'ftp']def __init__(self, redirect_to, *args, **kwargs):super().__init__(*args, **kwargs)self['Location'] = iri_to_uri(redirect_to)parsed = urlparse(str(redirect_to))if parsed.scheme and parsed.scheme not in self.allowed_schemes:raise DisallowedRedirect("Unsafe redirect to URL with protocol '%s'" % parsed.scheme)url = property(lambda self: self['Location'])def __repr__(self):return '<%(cls)s status_code=%(status_code)d%(content_type)s, url="%(url)s">' % {'cls': self.__class__.__name__,'status_code': self.status_code,'content_type': self._content_type_for_repr,'url': self.url,}class HttpResponseRedirect(HttpResponseRedirectBase):status_code = 302class HttpResponsePermanentRedirect(HttpResponseRedirectBase):status_code = 301

逐行解析

1. 基類:HttpResponseRedirectBase
class HttpResponseRedirectBase(HttpResponse):allowed_schemes = ['http', 'https', 'ftp']
  • 繼承:它繼承自 HttpResponse,這意味著它擁有所有普通HTTP響應的特性(如狀態碼、頭部、內容等),并在此基礎上增加了重定向的特殊功能。
  • 類屬性 allowed_schemes:這是一個非常重要的安全特性。它定義了一個白名單,列出了允許重定向到的URL協議(scheme)。默認只允許 'http', 'https', 'ftp'。這可以防止一種稱為不安全的URL重定向的安全漏洞,例如,如果有人試圖構造一個 javascript:alert('xss')data:text/html;base64,... 這樣的惡意鏈接,由于其協議(javascript:, data:)不在白名單內,重定向將會被阻止并拋出異常。
    def __init__(self, redirect_to, *args, **kwargs):super().__init__(*args, **kwargs)
  • 構造函數:接受一個必需的參數 redirect_to(要重定向到的目標URL),以及其他任何父類 HttpResponse 可能接受的參數(如 content, content_type 等)。
  • 調用父類構造函數super().__init__(*args, **kwargs) 確保 HttpResponse 被正確初始化。
        self['Location'] = iri_to_uri(redirect_to)
  • 設置Location頭部:這是實現重定向的關鍵。HTTP協議規定,重定向響應必須在 Location 頭部中包含目標URL。這里通過將字典式的賦值(self['Location'])來設置響應頭。
  • iri_to_uri函數:這是一個Django的工具函數,用于將國際化資源標識符(IRI) 轉換為標準的統一資源標識符(URI)。IRI支持Unicode字符(如中文),而URI只允許使用ASCII字符。這個函數會正確處理非ASCII字符的編碼(例如,將“中文”轉換為%E4%B8%AD%E6%96%87)。
        parsed = urlparse(str(redirect_to))if parsed.scheme and parsed.scheme not in self.allowed_schemes:raise DisallowedRedirect("Unsafe redirect to URL with protocol '%s'" % parsed.scheme)
  • 安全驗證
    1. urlparse(str(redirect_to)):使用Python的 urllib.parse.urlparse 函數解析目標URL,將其拆分成各個組成部分(scheme, netloc, path等)。
    2. 檢查解析出的協議(parsed.scheme)是否存在且不在允許的協議白名單(self.allowed_schemes)中。
    3. 如果協議不被允許,則拋出一個 DisallowedRedirect 異常,中止重定向過程。這是防止安全漏洞的關鍵防線。
    url = property(lambda self: self['Location'])
  • 只讀屬性 url:使用 property 裝飾器創建了一個名為 url 的只讀屬性。當你訪問 response.url 時,它會返回 Location 頭部的值,即重定向的目標URL。這提供了一個非常方便和直觀的訪問方式。
    def __repr__(self):return '<%(cls)s status_code=%(status_code)d%(content_type)s, url="%(url)s">' % {'cls': self.__class__.__name__,'status_code': self.status_code,'content_type': self._content_type_for_repr,'url': self.url,}
  • 對象表示:定義了 __repr__ 方法,當你在Python shell中打印這個響應對象時,它會返回一個格式化的、信息豐富的字符串,而不是默認的晦澀的內存地址。例如:<HttpResponseRedirect status_code=302, url="https://example.com/">。這在調試時非常有用。

2. 具體實現類:HttpResponseRedirectHttpResponsePermanentRedirect

這兩個類非常簡單,它們只做了一件事:繼承基類并設置正確的HTTP狀態碼。

class HttpResponseRedirect(HttpResponseRedirectBase):status_code = 302
  • 302 臨時重定向:HTTP狀態碼302表示所請求的資源暫時位于另一個URI下。客戶端(如瀏覽器或搜索引擎爬蟲)在遇到此重定向時,應該繼續使用原始URL發起請求,因為這次重定向可能是臨時的。
class HttpResponsePermanentRedirect(HttpResponseRedirectBase):status_code = 301
  • 301 永久重定向:HTTP狀態碼301表示所請求的資源已永久移動到新的URI。客戶端(尤其是搜索引擎爬蟲)在遇到此重定向后,應該更新其書簽或索引,將來所有的請求都應直接發送到新的URL。這對SEO有重要意義。

總結與使用場景

特性HttpResponseRedirect (302)HttpResponsePermanentRedirect (301)
狀態碼302301
語義臨時移動永久移動
瀏覽器行為會繼續使用原URL發起請求可能會緩存重定向,后續直接請求新URL
SEO影響原URL的權重和排名通常不會傳遞到新URL原URL的權重和排名會傳遞到新URL
常見使用場景用戶登錄后跳轉、表單提交后跳轉(Post/Redirect/Get模式)網站改版更換URL結構、HTTP升級到HTTPS

在實際視圖中的用法

在Django視圖中,你通常不會直接實例化這些類,而是使用更簡短的快捷函數 redirect(),它內部就是創建這些類的實例。

等效的寫法:

from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
from django.shortcuts import redirect# 方法一:直接使用類(顯式,稍顯冗長)
def my_view(request):return HttpResponseRedirect('/some/url/')# 或者 return HttpResponsePermanentRedirect('/some/url/')# 方法二:使用redirect()快捷函數(推薦,更靈活)
def my_view(request):# redirect() 函數默認返回 302 重定向return redirect('/some/url/') # 可以傳遞一個模型對象,它會自動調用 get_absolute_url()# return redirect(some_model_object) # 可以傳遞一個視圖名和參數# return redirect('view-name', arg=arg) # 要返回 301 重定向,使用 permanent 參數return redirect('/some/url/', permanent=True)

總之,這段代碼展示了Django如何通過面向對象的繼承和組合,構建出一個既安全(通過協議白名單和IRI轉換)又靈活(通過基類和不同狀態碼的子類)的重定向響應體系。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/98011.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/98011.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/98011.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Java實戰?】從IO到NIO:Java高并發編程的飛躍

目錄一、NIO 與 IO 的深度剖析1.1 IO 的局限性1.2 NIO 核心特性1.3 NIO 核心組件1.4 NIO 適用場景二、NIO 核心組件實戰2.1 Buffer 緩沖區2.2 Channel 通道2.3 Selector 選擇器2.4 NIO 文件操作案例三、NIO2.0 實戰3.1 Path 類3.2 Files 類3.3 Files 類高級操作3.4 NIO2.0 實戰…

OpenCV 實戰:圖像模板匹配與旋轉處理實現教程

目錄 一、功能概述&#xff1a;代碼能做什么&#xff1f; 二、環境準備&#xff1a;先搭好運行基礎 1. 安裝 Python 2. 安裝 OpenCV 庫 3. 準備圖像文件 三、代碼逐段解析&#xff1a;從基礎到核心 1. 導入 OpenCV 庫 2. 讀取圖像文件 3. 模板圖像旋轉&#xff1a;處理…

一、cadence的安裝及入門教學(反相器的設計與仿真)

一、Cadence的安裝 1、安裝VMware虛擬機 2、安裝帶有cadence軟件的Linux系統 注&#xff1a;網盤鏈接 分享鏈接&#xff1a;https://disk.ningsuan.com.cn/#s/8XaVdtRQ 訪問密碼&#xff1a;11111 所有文件壓縮包及文檔密碼&#xff1a; Cadence_ic 3、安裝tsmc18工藝庫…

用ai寫了個UE5插件

文章目錄實際需求1.頭文件2.源文件3.用法小結實際需求 這個需求來源于之前的一個項目&#xff0c;當時用了一個第三方插件&#xff0c;里邊有一些繪制線段的代碼&#xff0c;c層用的是drawdebugline&#xff0c;當時看底層&#xff0c;覺得應該沒問題&#xff0c;不應該在rele…

機器學習從入門到精通 - 強化學習初探:Q-Learning到Deep Q-Network實戰

機器學習從入門到精通 - 強化學習初探&#xff1a;從 Q-Learning 到 Deep Q-Network 實戰 一、開場白&#xff1a;推開強化學習這扇門 不知道你有沒有過這種感覺 —— 盯著一個復雜的系統&#xff0c;既想讓它達到某個目標&#xff0c;又苦于無法用傳統規則去精確描述每一步該怎…

【OpenHarmony文件管理子系統】文件訪問接口解析

OpenHarmony文件訪問接口&#xff08;filemanagement_file_api&#xff09; 概述 OpenHarmony文件訪問接口&#xff08;filemanagement_file_api&#xff09;是開源鴻蒙操作系統中的核心文件系統接口&#xff0c;為應用程序提供了完整的文件IO操作能力。該項目基于Node-API&…

云手機運行是否消耗自身流量?

云手機運行是否消耗自身流量&#xff0c;取決于具體的使用場景和設置&#xff1a;若用戶在連接云手機時&#xff0c;使用的是家中Wi-Fi、辦公室局域網等非移動數據網絡&#xff0c;那么在云手機運行過程中&#xff0c;基本不會消耗用戶自身的移動數據流量&#xff0c;在家中連接…

JavaSe之多線程

一、多線程基本了解 1、多線程基本知識 1.進程:進入到內存中執行的應用程序 2.線程:內存和CPU之間開通的通道->進程中的一個執行單元 3.線程作用:負責當前進程中程序的運行.一個進程中至少有一個線程,一個進程還可以有多個線程,這樣的應用程序就稱之為多線程程序 4.簡單理解…

產品月報|睿本云8月產品功能迭代

睿本云8月更新已陸續上線&#xff01; 睿本云8月產品月報&#xff0c;點擊查收&#x1f447;小程序支付成功彈窗廣告、企業會員增加卡券銷售和卡券退貨模塊、工廠端可批量新增多門店訂貨單、門店端和工廠端新增“極速訂貨”、商品調撥業務支持自定義多種流程配置等功能迭代更新…

融云:當我們談論 AI 重構業務時,我們到底在談論什么

所有業務都值得用 AI 重新做一次。 這句話正在從一句鼓舞人心的口號&#xff0c;演變為一場無人可避的商業現實。AI 帶來的結構性機會&#xff0c;意味著企業有機會從根本上重構成本、效率與體驗的曲線。但這一切最終都要回到一個無比務實的問題上&#xff1a; AI 究竟如何在我…

org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1異常

org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length 1異常問題解決一、問題背景二、錯誤現象三、原因分析核心問題&#xff1a;字符集不匹配四、解決過程試錯路徑記錄五、最終方案1.創建launch.json文件&#xff0c;修改VSCode…

【C語言】深入理解指針(5)

目錄 sizeof和strlen 1.sizeof 2.strlen 3. sizeof 和 strlen 的對比 sizeof和strlen 1.sizeof sizeo正名&#xff1a;sizeof是操作符&#xff0c;不是函數&#xff0c;sizeof是操作符&#xff0c;括號內如果有計算不會進行計算sizeof 是操作符&#xff0c;用于計算變量所…

動態代理設計模式

JDK動態代理實現 動態代理利用了JDK API,動態地在內存中構建代理對象,從而實現對目標對象的代理功能.動態代理又被稱為JDK代理或接口代理. 靜態代理與動態代理的區別: 靜態代理在編譯時就已經實現了,編譯完成后代理類是一個實際的class文 動態代理是在運行時動態生成的,即編譯…

《Html泛型魔法學院:用霍格沃茨風格網頁教授集合框架》

一、項目概述 這個創意教學網頁&#xff0c;將Java泛型與集合框架知識融入霍格沃茨魔法世界主題。通過沉浸式UI設計和交互式代碼練習&#xff0c;讓抽象的技術概念變得生動有趣。主要技術棧包括&#xff1a; HTML5語義化結構Tailwind CSS框架Font Awesome圖標庫純JavaScript交…

學習PaddlePaddle--環境配置-PyCharm + Conda?

第一階段&#xff1a;安裝與配置 Python 和 Conda?? 雖然 PyCharm 可以管理環境&#xff0c;但我們先獨立準備好 Conda 環境&#xff0c;這樣更清晰可靠。 ??1. 安裝 Miniconda (Python 環境管理)?? 1. ??下載??&#xff1a; ? 訪問 Miniconda 官網。 ? 選擇 ??M…

【數據庫】Sql Server數據庫中isnull、iif、case when三種方式的使用和空值判斷

大家好&#xff0c;我是全棧小5&#xff0c;歡迎來到《小5講堂》。 這是《Sql Server》系列文章&#xff0c;每篇文章將以博主理解的角度展開講解。 溫馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不對之處望指正&#xff01; 目錄前言ISNULL用法c…

【藍橋杯選拔賽真題64】C++最大空白區 第十四屆藍橋杯青少年創意編程大賽 算法思維 C++編程選拔賽真題解

C++最大空白區 第十四屆藍橋杯青少年創意編程大賽C++選拔賽真題 博主推薦 所有考級比賽學習相關資料合集【推薦收藏】 1、C++專欄 電子學會C++一級歷年真題解析 電子學會C++二級歷年真題解析

試用Augment編寫python腳本實現智能家居3D環境交互響應

環境配置 VS Code中直接安裝Augment擴展&#xff0c;然后郵箱登錄就能獲得7天的試用。 從如下位置安裝3D建模軟件Blender&#xff1a; https://www.blendercn.org/downloadme#xiazai Blender 是一款免費開源的 3D 創作套件。它支持整個三維流程&#xff1a;建模、綁定、動畫…

【架構師干貨】系統架構設計

1. 軟件架構概述 從需求分析到軟件設計之間的過渡過程稱為軟件架構。只要軟件架構設計好了&#xff0c;整個軟件就不會出現坍塌性的錯誤&#xff0c;即不會崩潰。 架構設計就是需求分配&#xff0c;將滿足需求的職責分配到組件上。 軟件架構為軟件系統提供了一個結構、行為和屬…

Java設計模式之結構型—享元模式

Java中最常用的設計模式-CSDN博客 把“不可變且可復用”的細粒度對象緩存起來&#xff0c;用“共享”代替“新建”&#xff0c;從而節省內存。 經典場景 字符串常量池、Integer.valueOf(-128~127)、Android Message.obtain() 游戲粒子、編輯器字形、地圖瓦片、線程池中的任務…