做網(wǎng)站的企業(yè)排名站長平臺(tái)工具
系列文章目錄
- Django入門全攻略:從零搭建你的第一個(gè)Web項(xiàng)目
- Django ORM入門指南:從概念到實(shí)踐,掌握模型創(chuàng)建、遷移與視圖操作
- Django ORM實(shí)戰(zhàn):模型字段與元選項(xiàng)配置,以及鏈?zhǔn)竭^濾與QF查詢?cè)斀?/li>
- Django ORM深度游:探索多對(duì)一、一對(duì)一與多對(duì)多數(shù)據(jù)關(guān)系的奧秘與實(shí)踐
- 跨域問題與Django解決方案:深入解析跨域原理、請(qǐng)求處理與CSRF防護(hù)
- Django視圖層探索:GET/POST請(qǐng)求處理、參數(shù)傳遞與響應(yīng)方式詳解
- Django路由與會(huì)話深度探索:靜態(tài)、動(dòng)態(tài)路由分發(fā),以及Cookie與Session的奧秘
- …(可在同專欄下查看最近更新文章)
文章目錄
- 系列文章目錄
- 前言
- 一、靜態(tài)路由
- 1.1 靜態(tài)路由匹配方式:
- 1.2 靜態(tài)路由示例
- 二、動(dòng)態(tài)路由
- 2.1 動(dòng)態(tài)路由參數(shù)傳遞
- 2.2 動(dòng)態(tài)路由轉(zhuǎn)換器
- 2.3 動(dòng)態(tài)路由傳參與GET傳參的異同點(diǎn)
- 三、路由分發(fā)
- 3.1 路由分發(fā)的概念
- 3.2 include路由分發(fā)實(shí)現(xiàn)
- 四、Cookie
- 4.1 HTTP短連接是什么
- 4.2 狀態(tài)保持是什么
- 4.3 什么是COOKIE
- 4.4 框架對(duì)于COOKIE的操作
- 五、Session
- 5.1 Session的原理
- 5.2 框架是如何存儲(chǔ)管理Session的
- 5.3 框架如何操作Session
- 5.4 Session示例
- 5.5 Session與Cookie的對(duì)比
- 六、CSRF
- 6.1 什么是CSRF
- 6.2 CSRF攻擊模擬實(shí)現(xiàn)
- 6.3 如何防止CSRF攻擊
前言
????主要介紹了Django中靜態(tài)路由、動(dòng)態(tài)路由、路由分發(fā)、Cookie和Session以及CSRF等內(nèi)容
一、靜態(tài)路由
Django的路由系統(tǒng)中,通過urls的匹配,可以直接映射到特定的視圖函數(shù)或類視圖,在當(dāng)前整個(gè)路由中沒有攜帶任何動(dòng)態(tài)改變的值,稱之為靜態(tài)路由。
通俗來說,訪問路徑中,不存在動(dòng)態(tài)傳遞數(shù)據(jù),稱之為靜態(tài)路由
urlpatterns屬性:
urlpatterns
是路由文件中的一個(gè)全局變量,用來存放路由及視圖函數(shù)的映射關(guān)系
用戶發(fā)起的請(qǐng)求URL
都會(huì)首先進(jìn)入主控制目錄下的這個(gè)urls.py
文件中進(jìn)行查找匹配:
- 首先找到
urls.py
下的urlpatterns
全局變量,這是一個(gè)路由規(guī)則實(shí)例的列表數(shù)據(jù)。 - 按照先后定義順序,進(jìn)行路由匹配。
- 找到第一個(gè)匹配項(xiàng)時(shí)停止匹配,執(zhí)行匹配到的視圖函數(shù)。
- 遍歷完全,未發(fā)現(xiàn)匹配,
django
進(jìn)行異常處理
其中urlpatterns
中的每一個(gè)路由映射規(guī)則可以由path
或re_path
進(jìn)行構(gòu)造
1.1 靜態(tài)路由匹配方式:
path方法:
path(str, view, kwargs=None, name=None)
'''
str:一個(gè)匹配對(duì)應(yīng)url地址的規(guī)則字符串
view:路由對(duì)應(yīng)的視圖函數(shù),并且會(huì)自動(dòng)封裝HttpRequest作為第一個(gè)參數(shù)給這個(gè)視圖函
kwargs:視圖函數(shù)的關(guān)鍵字參數(shù)
name:該路由的全局命名,可以讓我們方便的在django項(xiàng)目中任意部分顯示的使用,相當(dāng)于為url取變量名,接下來全局使用該命名值即可;當(dāng)對(duì)應(yīng)url路由改變之后,結(jié)合路由反向解析使用的地方不需要更改路由,案例:<a href="{% url url_name %}"></a>
'''
re_path方法:
re_path(regex, view, kwargs=None, name=None)
'''
regex:一個(gè)匹配對(duì)應(yīng)url地址的規(guī)則字符串
view:路由對(duì)應(yīng)的視圖函數(shù),并且會(huì)自動(dòng)封裝HttpRequest作為第一個(gè)參數(shù)給這個(gè)視圖函
kwargs:視圖函數(shù)的關(guān)鍵字參數(shù)
name:該路由的全局命名,可以讓我們方便的在django項(xiàng)目中任意部分顯示的使用,相當(dāng)于為url取變量名,接下來全局使用該命名值即可;當(dāng)對(duì)應(yīng)url路由改變之后,結(jié)合路由反向解析使用的地方不需要更改路由
'''
1.2 靜態(tài)路由示例
# views.py
from django.http import HttpResponse
def index(request):return HttpResponse('Hello Worlds!') # urls.py
from django.urls import path,re_path
from urlapp import views
urlpatterns = [path('index/',views.index),re_path(r"^/$",views.index),#此處完善對(duì)應(yīng)的正則表達(dá)式即可re_path(r"^index/\d+/$",IndexView.as_view()), #CBV
]
二、動(dòng)態(tài)路由
動(dòng)態(tài)路由:訪問路徑中,存在動(dòng)態(tài)傳遞數(shù)據(jù),稱之為動(dòng)態(tài)路由
2.1 動(dòng)態(tài)路由參數(shù)傳遞
例如在遇到一些內(nèi)容翻頁的場(chǎng)景時(shí),我們的連接可能是:xx.com/airticle_list/1/
、xx.com/airticle_list/2/
# views.py
def index(request,x,y):content = "x:%s\ny:%s" % (x,y) return HttpResponse(content)
定義如上函數(shù),將會(huì)接收連接中的后兩部份path
值作為參數(shù),分別依次給到x
和y
2.2 動(dòng)態(tài)路由轉(zhuǎn)換器
# urls.py
from django.urls import path,re_path
from urlapp import views
urlpatterns = [path('<int:x>/<str:y>/',views.index), # 指明類型 訪問:`http://127.0.0.1:8000/1/abc/`path("<x>/<y>/",views.index), # 不指明類型 訪問:`http://127.0.0.1:8000/abc/abc/`re_path(r"^(?P<x>\d+)/(?P<y>[a-zA-Z]+)/$"), # (?P<name>pattern) 正則分組re_path(r"^(\d+)/([a-zA-Z]+)/$"),
]
- 其他內(nèi)置Path轉(zhuǎn)換器,可以將我們的路由參數(shù)規(guī)定為指定類型
'''
str:匹配除了路徑分隔符(`/`)之外的非空字符串,這是默認(rèn)的形式
int:匹配正整數(shù),包含0
slug:匹配字母、數(shù)字以及橫杠、下劃線組成的字符串
uuid:匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00
path:匹配任何非空字符串,包含了路徑分隔符
'''
自定義轉(zhuǎn)換器:
在Django中,自定義路由轉(zhuǎn)換器(Custom Route Converter) 允許你根據(jù)特定的正則表達(dá)式和規(guī)則來定義如何解析URL中的參數(shù),并將其傳遞給視圖函數(shù)或類視圖。這種機(jī)制允許你更加靈活地處理URL模式,尤其是當(dāng)內(nèi)置的路由轉(zhuǎn)換器(如
int
、slug
、path
等)無法滿足你的需求時(shí)。
# urls.py
from django.urls import path,re_path,converters
class PhoneConverter:regex = '1[3-9]\d{9}'def to_python(self, value):return int(value)def to_url(self, value):return str(value)#在 項(xiàng)目的 urls.py 文件中 注冊(cè) 自定義的路由轉(zhuǎn)換器
converters.register_converter(PhoneConverter, 'phone')
#在路由配置中
urlpatterns = [path('index/<phone:id>/',views.index), # 指明類型
]
2.3 動(dòng)態(tài)路由傳參與GET傳參的異同點(diǎn)
- 動(dòng)態(tài)路由傳參,參數(shù)需要參與路由匹配,在路由匹配中獲取參數(shù)
- GET參數(shù),參數(shù)部分不需要參與路由匹配,在視圖中獲取參數(shù)
三、路由分發(fā)
3.1 路由分發(fā)的概念
每個(gè)子
app
都擁有自己獨(dú)立的urls.py
路由映射文件,而主控路由文件里只需要使用include
函數(shù)導(dǎo)入子app
下路由文件即可,這就是路由分發(fā)
3.2 include路由分發(fā)實(shí)現(xiàn)
from django.contrib import admin
from django.urls import path,includeurlpatterns = [path('admin/', admin.site.urls),path('urlapp/',include("urlapp.urls")) # 使用include 實(shí)現(xiàn)路由分發(fā),找到子app下的路由文件
]
四、Cookie
4.1 HTTP短連接是什么
HTTP短連接
,也稱為非持久連接,在HTTP/1.0中,默認(rèn)使用的是短連接。也就是說,瀏覽器和服務(wù)器每進(jìn)行一次HTTP操作,就建立一次連接,但任務(wù)結(jié)束就中斷連接。
HTTP長連接
,也稱為持久連接(Persistent Connection)或HTTP keep-alive連接,是一種使用單個(gè)TCP連接來發(fā)送和接收多個(gè)HTTP請(qǐng)求/響應(yīng)的通信方式。HTTP/1.1起,默認(rèn)使用長連接。與HTTP短連接不同,長連接在發(fā)送一個(gè)HTTP請(qǐng)求后不會(huì)立即關(guān)閉TCP連接,而是保持連接打開狀態(tài),以便在同一連接上發(fā)送和接收后續(xù)的HTTP請(qǐng)求/響應(yīng)。
4.2 狀態(tài)保持是什么
Cookie
及Session
一直以來都是Web開發(fā)中非常關(guān)鍵的一環(huán),因?yàn)?code>HTTP協(xié)議本身為無狀態(tài),每一次請(qǐng)求之間沒有任何狀態(tài)信息保持,往往我們的Web服務(wù)無法在客戶端訪問過程中得知用戶的一些狀態(tài)信息,比如是否登錄等等;那么這里通過引入Cookie
或者Seesion
來解決這個(gè)問題
客戶端存儲(chǔ)信息使用:Cookie
服務(wù)端存儲(chǔ)信息使用:Session
4.3 什么是COOKIE
當(dāng)客戶端訪問時(shí),服務(wù)端會(huì)為客戶端生成一個(gè)
Cookie
鍵值對(duì)數(shù)據(jù),通過Response
響應(yīng)給到客戶端。當(dāng)下一次客戶端繼續(xù)訪問相同的服務(wù)端時(shí),瀏覽器客戶端就會(huì)將這個(gè)Cookie
值連帶發(fā)送到服務(wù)端.
Cookie
是基于客戶端的,它們與用戶的瀏覽器會(huì)話相關(guān)聯(lián)。服務(wù)器使用Cookie
來跟蹤和識(shí)別用戶的瀏覽器會(huì)話,以便為用戶提供個(gè)性化的體驗(yàn)或記住用戶的設(shè)置和偏好。
Cookie 主要由以下幾部分組成:
- 名稱(Name):Cookie 的名稱,用于標(biāo)識(shí)該 Cookie
- 值(Value):與 Cookie 名稱關(guān)聯(lián)的值,通常用于存儲(chǔ)用戶信息或狀態(tài)。
- 過期時(shí)間(Expires/Max-Age):指定 Cookie 的有效期。如果設(shè)置了過期時(shí)間,則 Cookie 會(huì)在該時(shí)間后自動(dòng)失效;否則,Cookie 將在瀏覽器關(guān)閉時(shí)失效。
- 路徑(Path):指定 Cookie 適用的頁面路徑。只有該路徑下的頁面才能訪問該 Cookie。
- 域(Domain):指定可以接收該 Cookie 的域名。通常設(shè)置為設(shè)置該 Cookie 的網(wǎng)站的域名。
- 安全標(biāo)志(Secure):如果設(shè)置了該標(biāo)志,則只能通過 HTTPS 協(xié)議傳輸該 Cookie。這有助于增加 Cookie 的安全性。
- HttpOnly 標(biāo)志:如果設(shè)置了該標(biāo)志,則 JavaScript 無法訪問該 Cookie。這有助于防止跨站腳本攻擊(XSS)。
4.4 框架對(duì)于COOKIE的操作
在
django
的代碼中,我們可以使用一些提供Response
響應(yīng)的類,如:HttpResponse
,redirect
等實(shí)例的內(nèi)置set_cookie
函數(shù)來進(jìn)行django
項(xiàng)目中的Cookie
設(shè)置
set_cookie(key, value='', max_age=None, expires=None, path='/',domain=None, secure=False, httponly=False)
'''
參數(shù)解釋:
key: Cookie的key值,未來通過該key值獲取到對(duì)應(yīng)設(shè)置好的Cookie。
value='': 對(duì)應(yīng)Cookie的key值的value,比如: set_cookie(key='value',value='shuai')
max_age=None: Cookie生效的時(shí)間,單位為秒,如果Cookie值只持續(xù)在客戶端瀏覽器的會(huì)話時(shí)長,那么這個(gè)值應(yīng)該為None。存在該值時(shí),expires會(huì)被計(jì)算得到。
expires=None: Cookie具體過期日期,是一個(gè)datetime.datetime對(duì)象,如果該值存在,那么max_age也會(huì)被計(jì)算得到
如果同時(shí)設(shè)置了expires和max_age,老版本中以expires為準(zhǔn),新版本中會(huì)報(bào)錯(cuò),建議使用:單獨(dú)使用max_agepath='/': 指定哪些url可以訪問到Cookie,默認(rèn)/為所有。
domain=None: 當(dāng)我們需要設(shè)置的為一個(gè)跨域的Cookie值,那么可以使用該參數(shù),比如: domain='.test.com',那么這個(gè)Cookie值可以被www.test.com、bbs.test.com等主域名相同的域所讀取,否則Cookie只被設(shè)置的它的域所讀取。為None時(shí),代表當(dāng)前域名下全局生效。
secure=False: https加密傳輸設(shè)置,當(dāng)使用https協(xié)議時(shí),需要設(shè)置該值,同樣的,如果設(shè)置該值為True,如果不是https連接情況下,不會(huì)發(fā)送該Cookie值。
httponly=False: HTTPOnly是包含在HTTP響應(yīng)頭部中Set-Cookie中的一個(gè)標(biāo)記。為一個(gè)bool值,當(dāng)設(shè)置為True時(shí),代表阻止客戶端的Javascript訪問Cookie。這是一種降低客戶端腳本訪問受保護(hù)的Cookie數(shù)據(jù)風(fēng)險(xiǎn)的有效的辦法。
'''
設(shè)置COOKIE:
# views.py
from django.shortcuts import render,HttpResponse
# Create your views here.def set_cookie(request):# 在HTTPResponse部分設(shè)置COOKIE值cookie_reponse = HttpResponse('這是一個(gè)關(guān)于cookie的測(cè)試')cookie_reponse.set_cookie('test','hello cookie')return cookie_reponse
以上視圖函數(shù)返回一個(gè)
HttpResponse
對(duì)象,并在該對(duì)象中集成COOKIE
值的設(shè)定,設(shè)置key
值為test
,value
值為hello cookie
設(shè)置過期時(shí)間:
import datetime
current_time = datetime.datetime.now() # 當(dāng)前時(shí)間
expires_time = current_time + datetime.timedelta(seconds=10) # 向后推延十秒
set_cookie('key','value',expires=expires_time) #設(shè)置Cookie及對(duì)應(yīng)超時(shí)時(shí)間datetime.timedelta是Python中一個(gè)用于表示時(shí)間差的類。它可以表示一段時(shí)間,例如幾天、幾小時(shí)、幾分鐘等。使用datetime.timedelta可以在日期和時(shí)間上進(jìn)行簡單的加減操作。
獲取COOKIE:
def get_cookie(request):# 獲取cookie值,從request屬性中的COOKIE屬性中cookie_data = request.COOKIES.get('test')return HttpResponse('Cookie值為:%s' % cookie_data)
Cookie
值存儲(chǔ)在request
中的COOKIES
屬性中
并且該屬性獲取到的結(jié)果與python中的字典類似,直接通過內(nèi)置函數(shù)get
獲取即可
刪除COOKIE:
def delete_cookie(request):response = HttpResponseRedirect('/check_cookie/')response.delete_cookie('test')return response
在Cookie
中刪除指定的key
及對(duì)應(yīng)的value
,如果key
值不存在,也不會(huì)引發(fā)任何異常。
防止篡改COOKIE:
通過
set_signed_cookie
函數(shù)進(jìn)行持有簽名的COOKIE
值設(shè)置,避免用戶在客戶端進(jìn)行修改
HttpResonse.set_signed_cookie(key, value, salt='', max_age=None,
expires=None, path='/', domain=None, secure=None, httponly=True)
# 為cookie值添加簽名,其余參數(shù)與set_cookie相同
Request.get_signed_cookie(key, salt='', max_age=None)
# 從用戶請(qǐng)求中獲取通過salt鹽值加了簽名的`Cookie`值
這里的
salt
要與之前存儲(chǔ)時(shí)使用的salt
值相同才可以解析出正確結(jié)果。
還要注意的是,如果對(duì)應(yīng)的key值不存在,則會(huì)引發(fā)KeyError
異常,所以要記得異常捕獲來確定是否含有Cookie
值
def check_salt_cookie(request):try:salt_cookie = request.get_signed_cookie(key='salt_cookie',salt='nice')except KeyError: #獲取不到該key值的Cookieresponse = HttpResponse('正在設(shè)置一個(gè)salt Cookie值')response.set_signed_cookie(key='salt_cookie',salt='nice',value='salt_cookie')return responseelse: #獲取到了對(duì)應(yīng)key值,展示到新的HttpResonse中return HttpResponse('獲取到的salt Cookie值:%s' % salt_cookie)
五、Session
5.1 Session的原理
Session
在網(wǎng)絡(luò)中,又稱會(huì)話控制,簡稱會(huì)話。用以存儲(chǔ)用戶訪問站點(diǎn)時(shí)所需的信息及配置屬性。當(dāng)用戶在我們的Web
服務(wù)中跳轉(zhuǎn)時(shí),存儲(chǔ)在Session
中的數(shù)據(jù)不會(huì)丟失,可以一直在整個(gè)會(huì)話過程中存活。
5.2 框架是如何存儲(chǔ)管理Session的
在
django
中,默認(rèn)的Session
存儲(chǔ)在數(shù)據(jù)庫中session
表里。默認(rèn)有效期為兩個(gè)星期。
5.3 框架如何操作Session
當(dāng)
settings.py
中SessionMiddleware
激活后
在視圖函數(shù)的參數(shù)request
接收到的客戶端發(fā)來的HttpResquest
請(qǐng)求對(duì)象中都會(huì)含有一個(gè)session
屬性
存儲(chǔ)session:
request.session[key] = value
request.session['name'] = 'zs'
獲取Session:
session_data = request.session.get(Key)
session_data = request.session[Key]
在
Session
中獲取對(duì)應(yīng)值,get
方法獲取時(shí),如不存在該Key
值,不會(huì)引發(fā)異常,返回None
;
而第二種直接通過get方法獲取,如Key
值不存在,引發(fā)KeyError
刪除Session:
del request.seesion[Key]
# 刪除對(duì)應(yīng)session,Key值不存在時(shí),引發(fā)KeyErrorrequest.session.clear()
# 清空Session中的所有數(shù)據(jù)。這里客戶端還會(huì)保留sessionid;
# 只不過在服務(wù)端sessionid對(duì)應(yīng)的數(shù)據(jù)沒有了request.session.flush()
# 直接刪除當(dāng)前客戶端的的Seesion數(shù)據(jù)。這里不光服務(wù)端sessionid對(duì)應(yīng)的數(shù)據(jù)沒有了,客戶端的`sessionid`也會(huì)被刪除
設(shè)置有效期:
request.session.set_expiry(value)
# 設(shè)置Session的有效時(shí)間
'''
value: 有效時(shí)間。- 為整數(shù)時(shí): 將在value為秒單位之后過期 - 為0時(shí): 將在用戶關(guān)閉瀏覽器之后過期。- 為None時(shí): 使用全局過期的設(shè)置,默認(rèn)為兩個(gè)星期,14天。- 為datetime時(shí): 在這個(gè)指定時(shí)間后過期 2023-8-10 12:00:00
'''
request.session.get_expiry_age()
# 返回距離過期還剩下的秒數(shù)
request.session.clear_expired()
# 清除過期的Session會(huì)話
5.4 Session示例
from django.shortcuts import render,HttpResponseimport datetimedef set_session(request):if request.session.get('test_id'):session_data = request.session.get('test_id')# 用戶拿到的的session隨機(jī)字符串session_key = request.session.session_key # 獲取客戶端瀏覽器中的SessionID值session_expire = request.session.get_expiry_age()now = datetime.datetime.now()expire_time = now + datetime.timedelta(seconds=session_expire)response_body = '<div>SessionID : %s</div>' % session_key + \'<div>Session : %s</div>' % session_data + \'<div>ExpireTime : %s</div>' % expire_timereturn HttpResponse(response_body)else:request.session['test_id'] = 'TEST'request.session.set_expiry(None)return HttpResponse('已設(shè)置好Session')
用戶在第一次訪問時(shí),會(huì)走
else
分支,此時(shí)還沒有任何服務(wù)端的Session
及客戶端的Cookie
值設(shè)定
那么我們會(huì)通過request.session[Key]
的方式來設(shè)置一個(gè)Session
值,值為TEST
當(dāng)用戶第二次訪問時(shí)將展示出所設(shè)置好的
Session
值及在客戶端瀏覽器中存儲(chǔ)的sessionid
def delete_session(request):if request.session.get('test_id'):del request.session['test_id']return HttpResponse('Session被刪了')else:return HttpResponse('目前沒有任何需要?jiǎng)h除的session')
5.5 Session與Cookie的對(duì)比
1.cookie
數(shù)據(jù)存放在客戶的瀏覽器
上,session
數(shù)據(jù)放在服務(wù)器
上。
2. cookie不是很安全,別人可以分析存放在本地的COOKIE并進(jìn)行COOKIE欺騙,考慮到安全應(yīng)當(dāng)使用session。
3. session會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上。當(dāng)訪問增多,會(huì)比較占用你服務(wù)器的性能,考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用COOKIE。
4. 單個(gè)cookie保存的數(shù)據(jù)不能超過4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20個(gè)cookie。
六、CSRF
6.1 什么是CSRF
CSRF(Cross-site request forgery):跨站請(qǐng)求偽造。
6.2 CSRF攻擊模擬實(shí)現(xiàn)
從上圖可以看出,要完成一次 CSRF 攻擊,受害者必須滿足兩個(gè)必要的條件:
(1)登錄受信任網(wǎng)站 A,并在本地生成 Cookie。(如果用戶沒有登錄網(wǎng)站 A,那么網(wǎng)站 B 在誘導(dǎo)的時(shí)候,請(qǐng)求網(wǎng)站 A 的 api 接口時(shí),會(huì)提示你登錄)
(2)在不登出 A 的情況下,訪問危險(xiǎn)網(wǎng)站 B(其實(shí)是利用了網(wǎng)站 A 的漏洞)。
6.3 如何防止CSRF攻擊
討論 GET 和 POST 兩種請(qǐng)求,對(duì)于 GET,其實(shí)也沒什么需要防范的。為什么?
因?yàn)?GET 在 “約定” 當(dāng)中,被認(rèn)為是查詢操作,查詢的意思就是,你查一次,查兩次,無數(shù)次,結(jié)果都不會(huì)改變(用戶得到的數(shù)據(jù)可能會(huì)變),這不會(huì)對(duì)數(shù)據(jù)庫造成任何影響,所以不需要加其他額外的參數(shù)。
所以這里要提醒各位的是,盡量遵從這些約定,不要在 GET 請(qǐng)求中出現(xiàn) /delete, /update, /edit 這種單詞。把 “寫” 操作放到 POST 中。
對(duì)于 POST,服務(wù)端在創(chuàng)建表單的時(shí)候可以加一個(gè)隱藏字段,也是通過某種加密算法得到的。在處理請(qǐng)求時(shí),驗(yàn)證這個(gè)字段是否合法,如果合法就繼續(xù)處理,否則就認(rèn)為是惡意操作。
<form method="post" action="/delete"><!-- 其他字段 --><input type="hidden" />
</form>
這個(gè) html 片段由服務(wù)端生成。
這的確是一個(gè)很好的防范措施,再增加一些處理的話,還能防止表單重復(fù)提交。
可是對(duì)于一些新興網(wǎng)站,很多都采用了 “前后端分離開發(fā)” 的設(shè)計(jì),或者退一步,無論是不是前后端分離,它的 HTML 可能是由 JavaScript 拼接而成,并且表單也都是異步提交。所以這個(gè)辦法有它的應(yīng)用場(chǎng)景,也有局限性。