Flask 跨域問題

一、什么是跨域

跨域是指:瀏覽器A服務器B獲取的靜態資源,包括Html、Css、Js,然后在Js中通過Ajax訪問C服務器的靜態資源或請求。即:瀏覽器A從B服務器拿的資源,資源中想訪問服務器C的資源。

同源策略是指:瀏覽器A服務器B獲取的靜態資源,包括Html、Css、Js,為了用戶安全,瀏覽器加了限制,其中的Js通過Ajax只能訪問B服務器的靜態資源或請求。即:瀏覽器A從哪拿的資源,那資源中就只能訪問哪。

同源是指:同一個請求協議(如:Http或Https)、同一個Ip、同一個端口,3個全部相同,即為同源。

跨域的處理

W3C組織制定了一個Cross-Origin Resource Sharing規范,簡寫為Cors,現在這個規范已經被大多數瀏覽器支持,Cors 專門用來處理跨域的需求。

Cors需要在后端應用進行配置,因此,是一種跨域的后端處理方式,這么做也容易理解,一個你不認識的源來訪問你的應用,自然需要應用進行授權。除了后端處理方式,也有前端的解決方案,如:JSONP,這里我們主要講解Flask后端配置方案.

跨域的分類

跨域分為以下3種

名稱英文名說明
簡單請求Simple Request發起的Http請求符合:
1.無自定義請求頭,只有Accept、Accept-Language、Content-Language、Last-Event-ID
2.請求動詞為GET、HEAD或POST之一
3.動詞為POST時,Content-Type是application/x-www-form-urlencoded,multipart/form-data或text/plain之一
復雜請求Preflighted Request發起的Http請求符合其中之一:
1.包含了自定義請求頭
2.請求動詞不是GET、HEAD或POST
3.動詞是POST時, Content-Type不是application/x-www-form-urlencoded,multipart/form-data或text/plain。 即:簡單請求的相反
憑證請求Requests with Credential發起的Http請求中帶有憑證

簡單請求

簡單請求的發送從代碼上來看和普通的XHR沒太大區別,但是HTTP頭當中要求總是包含一個域(Origin)的信息。該域包含協議名、地址以及一個可選的端口。不過這一項實際上由瀏覽器代為發送,并不是開發者代碼可以觸及到的。

簡單請求的部分響應頭如下:

  1. Access-Control-Allow-Origin(必含)。不填,請求按失敗處理。該項控制數據的可見范圍,如果希望數據對任何人都可見,可以填寫"*"。
  2. Access-Control-Allow-Credentials(可選)。該項標志著請求當中是否包含cookies信息,只有一個可選值:true(必為小寫)。如果不包含cookies,請略去該項,而不是填寫false。這一項與XmlHttpRequest2對象當中的withCredentials屬性應保持一致,即withCredentials為true時該項也為true;withCredentials為false時,省略該項不寫。反之則導致請求失敗。
  3. Access-Control-Expose-Headers(可選) – 該項確定XmlHttpRequest2對象當中getResponseHeader()方法所能獲得的額外信息。通常情況下,getResponseHeader()方法只能獲得如下的信息:(當你需要訪問額外的信息時,就需要在這一項當中填寫并以逗號進行分隔)
    1. Cache-Control
    2. Content-Language
    3. Content-Type
    4. Expires
    5. Last-Modified
    6. Pragma

如果僅僅是簡單請求,那么即便不用CORS也沒有什么大不了,但CORS的復雜請求就令CORS顯得更加有用了。簡單來說,任何不滿足上述簡單請求要求的請求,都屬于復雜請求。比如說你需要發送PUT、DELETE等HTTP動作,或者發送Content-Type: application/json的內容。

復雜請求

復雜請求先發送一種"預請求",此時作為服務端,也需要返回"預回應"作為響應。預請求實際上是對服務端的一種權限請求,只有當預請求成功返回,實際請求才開始執行。預請求以OPTIONS形式發送,當中同樣包含域,并且還包含了兩項CORS特有的內容:

  1. Access-Control-Request-Method?– 該項內容是實際請求的種類,可以是GET、POST之類的簡單請求,也可以是PUT、DELETE等等。
  2. Access-Control-Request-Headers?– 該項是一個以逗號分隔的列表,當中是復雜請求所使用的頭部。

顯而易見,這個預請求實際上就是在為之后的實際請求發送一個權限請求,在預回應返回的內容當中,服務端應當對這兩項進行回復,以讓瀏覽器確定請求是否能夠成功完成。復雜請求的部分響應頭及解釋如下:

  1. Access-Control-Allow-Origin(必含) – 和簡單請求一樣的,必須包含一個域。
  2. Access-Control-Allow-Methods(必含) – 這是對預請求當中Access-Control-Request-Method的回復,這一回復將是一個以逗號分隔的列表。盡管客戶端或許只請求某一方法,但服務端仍然可以返回所有允許的方法,以便客戶端將其緩存。
  3. Access-Control-Allow-Headers(當預請求中包含Access-Control-Request-Headers時必須包含) – 這是對預請求當中Access-Control-Request-Headers的回復,和上面一樣是以逗號分隔的列表,可以返回所有支持的頭部。這里在實際使用中有遇到,所有支持的頭部一時可能不能完全寫出來,而又不想在這一層做過多的判斷,沒關系,事實上通過request的header可以直接取到Access-Control-Request-Headers,直接把對應的value設置到Access-Control-Allow-Headers即可。
  4. Access-Control-Allow-Credentials(可選) – 和簡單請求當中作用相同。
  5. Access-Control-Max-Age(可選) – 以秒為單位的緩存時間。預請求的的發送并非免費午餐,允許時應當盡可能緩存。

一旦預回應如期而至,所請求的權限也都已滿足,則實際請求開始發送。

目前大部分Modern瀏覽器已經支持完整的CORS,但IE直到IE11才完美支持,所以對于PC網站,還是建議采用其他解決方案,如果僅僅是移動端網站,大可放心使用。

Flask配置跨域

flask 配置cors 有兩種方式,一種使用自帶的cors,一種自定義返回頭

第一種,自定義返回頭

@app.after_request
def af_request(resp):     """#請求鉤子,在所有的請求發生后執行,加入headers。:param resp::return:"""resp = make_response(resp)resp.headers['Access-Control-Allow-Origin'] = '*'resp.headers['Access-Control-Allow-Methods'] = 'GET,POST'resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type'return resp

第二種,使用cors

Flask配Cors跨域,使用Flask-CORS包,詳細文檔,參見:?https://flask-cors.readthedocs.io/en/latest/

flask-cors 也提供了兩種方式:

方式

范圍

說明

@cross_origin裝飾器

配置單個路由

適用于配置特定的API接口

CORS函數

配置全局API接口

適用于全局的API接口配置

安裝flask-cors

pip install flask-cors

第一種:使用@cross_origin裝飾器

@app.route("/")
@cross_origin()
def helloWorld():return "Hello, cross-origin-world!"

CORS參數說明?

裝飾器參數

類型

Head字段

說明

origins

列表、字符串或正則表達式

Access-Control-Allow-Origin

配置允許跨域訪問的源,*表示全部允許

methods

列表、字符串

Access-Control-Allow-Methods

配置跨域支持的請求方式,如:GET、POST

expose_headers

列表、字符串

Access-Control-Expose-Headers

自定義請求響應的Head信息

allow_headers

列表、字符串或正則表達式

Access-Control-Request-Headers

配置允許跨域的請求頭

supports_credentials

布爾值

Access-Control-Allow-Credentials

是否允許請求發送cookie,false是不允許

max_age

整數、字符串

Access-Control-Max-Age

預檢請求的有效時長

第二種:使用CORS函數

#################### 應用全局配置 ####################
from flask_cors import *app = Flask(__name__)
CORS(app, supports_credentials=True, resources=r"/*")@app.route("/api/v1/users")
def list_users():return "user example"#################### 單獨Blueprints配置 ####################
api_v1 = Blueprint('API_v1', __name__)
CORS(api_v1) @api_v1.route("/api/v1/users/")
def list_users():return "user example"

CORS參數說明

參數

類型

Head字段

說明

resources

字典、迭代器或字符串

全局配置允許跨域的API接口

origins

列表、字符串或正則表達式

Access-Control-Allow-Origin

配置允許跨域訪問的源,*表示全部允許

methods

列表、字符串

Access-Control-Allow-Methods

配置跨域支持的請求方式,如:GET、POST

expose_headers

列表、字符串

Access-Control-Expose-Headers

自定義請求響應的Head信息

allow_headers

列表、字符串或正則表達式

Access-Control-Request-Headers

配置允許跨域的請求頭

supports_credentials

布爾值

Access-Control-Allow-Credentials

是否允許請求發送cookie,false是不允許

max_age

整數、字符串

Access-Control-Max-Age

預檢請求的有效時長

注意:繼承Resource類來寫的RESTful-API接口

繼承Resource類來寫的RESTful-API接口不能使用上述辦法。解決辦法是在需要支持跨域請求的API類下,添加一個類方法options,就可以解決跨域問題

原因是跨域問題請求的時候,無論是POST請求還是PUT請求,前端都會優先發起一個OPTIONS請求確認請求允許范圍.那么在解決跨域請求時,只需要在每個資源url中加入options請求方式,并返回適當的響應頭信息就能解決跨域問題.

class YourAPI(Resource):def options(self):return {'Allow': '*'}, 200, {'Access-Control-Allow-Origin': '*','Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, DELETE, PUT','Access-Control-Allow-Headers': 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild',}

具體可配置參數解釋:

  • Access-Control-Allow-Origin
    這個頭部信息由服務器返回,用來明確指定那些客戶端的域名允許訪問這個資源。它的值可以是:

    -使用" * " —— 允許任意域名

    • 一個完整的域名名字(比如:https://example.com)

    如果你需要客戶端傳遞驗證信息到頭部(比如:cookies)。這個值不能為 * —— 必須為完整的域名(這點很重要)。

  • Access-Control-Allow-Credentials
    這個頭部信息只會在服務器支持通過cookies傳遞驗證信息的返回數據里。它的值只有一個就是 true。跨站點帶驗證信息時,服務器必須要爭取設置這個值,服務器才能獲取到用戶的cookie。

  • Access-Control-Allow-Headers
    提供一個逗號分隔的列表表示服務器支持的請求數據類型。假如你使用自定義頭部(比如:x-authentication-token 服務器需要在返回OPTIONS請求時,要把這個值放到這個頭部里,否則請求會被阻止)。

  • Access-Control-Expose-Headers
    相似的,這個返回信息里包含了一組頭部信息,這些信息表示那些客戶端可以使用。其他沒有在里面的頭部信息將會被限制(譯者注:這個頭信息實戰中使用較少)。

  • Access-Control-Allow-Methods
    一個逗號分隔的列表,表明服務器支持的請求類型(比如:GET, POST)

  • Origin
    這個頭部信息,屬于請求數據的一部分。這個值表明這個請求是從瀏覽器打開的哪個域名下發出的。出于安全原因,瀏覽器不允許你修改這個值。

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

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

相關文章

Hibernate 中配置屬性詳解(hibernate.properties)

轉自:https://blog.csdn.net/shudaqi2010/article/details/70324843 Hibernate能在各種不同環境下工作而設計的, 因此存在著大量的配置參數。多數配置參數都 有比較直觀的默認值, 并有隨 Hibernate一同分發的配置樣例hibernate.properties 來展示各種配置選項。 所需…

1.3 使用電腦測試MC20的電話語音功能

需要準備的硬件 MC20開發板 1個https://item.taobao.com/item.htm?id562661881042GSM/GPRS天線 1根https://item.taobao.com/item.htm?id531979567261IPEX接口轉SMA接口轉接線 1根https://item.taobao.com/item.htm?id531979903836GPS有源天線 1根https://item.taobao.com/i…

前端之 AJAX

AJAX參數詳細列表 參數名類型描述urlString(默認: 當前頁地址) 發送請求的地址。typeString(默認: "GET") 請求方式 ("POST" 、 "GET")。注意:其它 HTTP 請求方法,如 PUT 和 DELETE ,但僅部分瀏覽器支持。tim…

buffer 和cache的區別

Cache:高速緩存,是位于CPU與主內存間的一種容量較小但速度很高的存儲器。 由于CPU的速度遠高于主內存,CPU直接從內存中存取數據要等待一定時間周期,Cache中保存著CPU剛用過或循環使用的一部分數據,當CPU再次使用該部分…

html5--1.18 div元素與布局

1.18 div元素與布局 1.元素的分類2.div元素與布局 1、元素的分類 塊元素:主要特征是會產生換行效果,自動與其他元素分離成兩行;通常可以作為容器在內部添加其他元素。已經學過的塊元素有: h1~h6;hr;ul;ol;p;table......... 內聯元素:不會產生…

python讀取excel表格太大怎么辦_Python:使用Openpyxl讀取大型Excel工作表

嘗試對load_workbook()類使用read_only True屬性,這會導致您獲得的工作表為IterableWroksheet,這意味著您只能迭代它們,您不能直接使用列/行號來訪問其中的單元格值.根據documentation,這將提供接近恒定的存儲器消耗.此外,您不需要關閉文件,語句將為您處理.示例 –import open…

五個優秀的視頻格式轉換工具

電腦、手機、DVD播放機、PSP……這么多的東西都可以播放視頻,但是視頻格式又千差萬別的,我們該怎么辦?這里,我們介紹五個功能強大且易于使用的媒體轉換器,用于轉換不同類型的視頻文件。 一、Super (Windows) Super是一…

前端之 HTML

HTML Web服務本質 import socketsk socket.socket() sk.bind(("127.0.0.1", 8080)) sk.listen(5)while True:conn, addr sk.accept()data conn.recv(8096)conn.send(b"HTTP/1.1 200 OK\r\n\r\n")conn.send(b"<h1>Hello world!</h1>&…

接入指南

接入概述 接入微信公眾平臺開發&#xff0c;開發者需要按照如下步驟完成&#xff1a; 1、填寫服務器配置 2、驗證服務器地址的有效性 3、依據接口文檔實現業務邏輯 下面詳細介紹這3個步驟。 第一步&#xff1a;填寫服務器配置 登錄微信公眾平臺官網后&#xff0c;在公眾平臺官網…

艾賓浩斯記憶表格excel_Excel全年學習復習計劃表(艾賓浩斯遺忘曲線)

最近準備考在職博士&#xff0c;刷刷學歷&#xff0c;不得不又拿起必考的英語來&#xff0c;發現由于這幾年敲代碼&#xff0c;日常生活詞匯忘了很多&#xff0c;只好買本考博詞匯背誦&#xff0c;不過三十而立的人背起來確實費勁了&#xff0c;所以開始尋找好的背誦方法。又想…

七個幫助你處理Web頁面層布局的jQuery插件

1.UI.Layout jQuery UI布局插件官方網站&#xff1a;http://layout.jquery-dev.com/index.cfm使用大小可折疊的嵌套面板和大量選項創建高級UI布局。布局可以創建任何你想要的UI外觀; 從簡單的標題或側邊欄到具有工具欄&#xff0c;菜單&#xff0c;幫助面板&#xff0c;狀態欄…

前端之 CSS

CSS介紹 CSS&#xff08;Cascading Style Sheet&#xff0c;層疊樣式表)定義如何顯示HTML元素。 當瀏覽器讀到一個樣式表&#xff0c;它就會按照這個樣式表來對文檔進行格式化&#xff08;渲染&#xff09;。 CSS語法 CSS實例 每個CSS樣式由兩個組成部分&#xff1a;選擇器…

在Window下編譯OpenH323

前言&#xff1a; 本文只提供VC6.0的編譯說明&#xff0c;如果想知道VC.Net下的編譯過程請參看原文。 原文 &#xff1a; http://www.voxgratia.org/docs/pwlib_windows.html#msvc_headers 作者 &#xff1a;Craig Southeren 翻譯 &#xff1a; Richard 原文…

shell中的條件判斷和比較

1 shell 的$! ,$?, $$,$ $n $1 the first parameter,$2 the second... $# The number of command-line parameters. $0 The name of current program. $? Last command or functions return value. $$ The programs PID. $! …

matlab立體坐標定位_無懼密集建筑,小天才立體定位技術帶來最強定位體驗

如今&#xff0c;在可穿戴設備市場中&#xff0c;智能手表占據相當大一部分。而作為核心功能之一的定位&#xff0c;在智能手表中發揮著不可替代的作用&#xff0c;尤其是對于兒童電話手表而言。并且&#xff0c;在技術飛速進步&#xff0c;產品迭代加快的當前&#xff0c;兒童…

vue學習問題總結(一)

使用comopontent組件報錯錯誤信息&#xff1a;vue.js:491 [Vue warn]: Unknown custom element: <todo-item> - did you register the component correctly? For recursive components, make sure to provide the "name" option.代碼&#xff1a;<p>使用…

前端之 JavaScript 基礎

JavaScript 概述 ECMAScript 和 JavaScript的關系 1996年11月&#xff0c;JavaScript 的創造者 Netscape(網景) 公司&#xff0c;決定將 JavaScript 提交給國際標準化組織 ECMA &#xff0c;希望這門語言能夠成為國際標準。次年&#xff0c;ECMA發布262號標準文件&#xff08…

TCPMP0.72RC1的編譯與移植以及自己另外做UI完整方法

我叫張挺&#xff0c;雖然開博&#xff0c;除了轉了一篇黃色文章以外&#xff0c;技術文章從來沒有寫&#xff0c;所以呢&#xff0c;感到很不好意思&#xff01;于是決定還寫一篇在網上也留點痕跡。我這里主要是介紹TCPMP的移植以及如何把這個鳥鳥整到自己的界面中來&#xff…

svga文件如何查看_電腦隱藏文件?如何查看隱藏文件 方法簡單易學

大家好&#xff0c;我是小白一鍵重裝軟件的客服。如何查看隱藏文件呢&#xff1f;有時候不小心把文件夾勾選隱藏后文件就消失了&#xff0c;到底是怎么回事呢&#xff1f;其實這個是電腦上面一些設置開啟了文件隱藏的功能哦&#xff0c;那么下面小白系統帶你了解下如何查看隱藏…

jquery 的animate 的transform

$(function(){ var t 1000; $("#id").animate( {borderSpacing:180}, //180 指旋轉度數 { step: function(now,fix){ $(this).css(-webkit-transform,rotate(nowdeg)); $(this).css(-ms-transform,rotate(nowdeg)); $(this).css(-moz-transform,rotate(nowdeg)); $(…