OPTIONS 方法比較少見,該方法用於請求服務器告知其支持哪些其他的功能和方法。通過 OPTIONS 方法,可以詢問服務器具體支持哪些方法,或者服務器會使用什么樣的方法來處理一些特殊資源。可以說這是一個探測性的方法,客戶端通過該方法可以在不訪問服務器上實際資源的情況下就知道處理該資源的最優方式。
既然比較少見,什么情況下會使用這個方法呢?
假設在 edx.open.com 域下發起了一個跨域的 POST 請求,期望提交數據到 api.sit.com 這個域名的服務器。
在進行發送POST請求前,會自動先發起一個 OPTIONS 請求,其請求頭包含了的一些關鍵性字段:
1 OPTIONS /upload/ HTTP/1.1 2 Access-Control-Request-Method: POST 3 Access-Control-Request-Headers: accept, content-type 4 Origin: http://edx.open.com 5 ...
這種場景下,客戶端發起的這個 OPTIONS 可以說是一個“預請求”,用於探測后續真正需要發起的跨域 POST 請求對於服務器來說是否是安全可接受的,因為跨域提交數據對於服務器來說可能存在很大的安全問題。
請求頭 Access-Control-Request-Method 用於提醒服務器在接下來的請求中將會使用什么樣的方法來發起請求。
那么在服務端應該如何處理這個 OPTIONS 請求呢?
響應上面的 OPTIONS 請求時,需要添加上用於訪問控制的響應頭。
響應頭中關鍵性的字段:
1 Access-Control-Allow-Method: POST 2 Access-Control-Allow-Origin: http://edx.open.com
3 Access-Control-Allow-Headers: X-CSRFToken, Content-Type
Access-Control-Allow-Method 和 Access-Control-Allow-Origin 分別告知客戶端,服務器允許客戶端用於跨域的方法和域名。
完整處理流程如下:
一.在視圖(我定義的是類視圖)中定義OPTIONS方法: def options(self, request, *args, **kwargs)/獲取請求頭的 Access-Control-Request-Method 和 Origin 參數
1 method = request.META.get('Access-Control-Allow-Method')
2 origin = request.META.get('Origin')
二.在def options(self, request, *args, **kwargs) 方法中 設置響應頭信息,返回response對象
1 response = Response() 2 response['Access-Control-Allow-Method'] = method # 支持那些請求方法,可以根據實際情況配置如 "POST, GET ,OPTIONS" 3 response['Access-Control-Allow-Origin'] = origin # 實際操作中本人無法獲取請求頭中的Origin參數,所以這里我實際上是配置成了 "*",但是不建議這樣操作,后續會有問題,可以根據實際情況寫成固定的也可以 "完整域名"
4 response["Access-Control-Allow-Headers"] = "X-CSRFToken, Content-Type" # 如果配置接收的請求頭有遺漏,當發送OPTIONS方法成功后,發送正式請求時將會在瀏覽器報錯,可以根據瀏覽器中consolo的報錯內容添加進去即可, 我這里需要配置的就是這兩個
5 return response
# OPTION方法定義完成后,還需要在正式的視圖方法中的響應對象中配置一樣的響應頭信息,這里不再重復了,至此,該視圖方法就支持跨域請求了。
# 需要留意的是,jquery發送OPTIONS請求時,默認將不會攜帶cookie信息,如果此時該視圖需要進行登錄驗證(跨域請求,卻要進行用戶驗證,這樣的場景往往存在於支持單點登錄功能的多個聯合平台中,如天貓和淘寶), 這時就需要在發送請求時在請求頭中進行相應的配置,具體這里就不細說了,想要了解 請點擊這里
# 但是我參照這種方式進行配置,options請求方法返回的都是403,所以我的處理方式是在接口(使用drf插件進行接口開發,使用drf的驗證功能 https://www.cnblogs.com/lowmanisbusy/p/8969771.html)注明允許所有用戶訪問,其實就相當於不進行登錄驗證,允許匿名用戶進行訪問(筆者所進行開發的項目如果不進行設置允許用戶以何種身份方式進行訪問,就會拋出異常),然后讓前端傳遞一個用戶名稱給我,再使用這個數據到用戶表查詢自己想要的用戶數據,實現功能
注意:
這里的OPTION方法中應該設置響應狀態碼為 204 是為了告知客戶端表示該響應成功了,但是該響應並沒有返回任何響應體,如果狀態碼為 200,還得攜帶多余的響應體,在這種場景下是完全多余的,只會浪費流量。
三.這里只是實現了單個視圖支持跨域請求,要實現全局支持跨域請求請點擊: https://www.cnblogs.com/lowmanisbusy/p/9589432.html