06 Python Flask 教學10 所有文章

【Flask教學系列】實作 Flask CORS

Flask教學_CORS_同源政策_Max行銷誌

一. 什麼是同源政策?

瀏覽器因為網頁安全性的考量,實施了同源政策 (Same-origin policy) ,所謂同源是指兩份網頁具有相同協定、埠號 (如果有指定) 以及主機位置,如果三項中有一個不相同,則視為非同源。當使用者發出非同源的 Request 請求時,瀏覽器會在 Response 時擋下來,並且回傳以下錯誤訊息。

打開開發者工具 console 可以看到顯示 No ‘Access-Control-Allow-Origin’ header 的錯誤訊息。

XMLHttpRequest cannot load 
http://example.com/user 
No 'Access-Control-Allow-Origin' header is present on the 
requested resource. Origin 'null' is therefore not allowed access.

二. 什麼是 CORS?

如果今天想在不同 origin 之間傳輸資料的話,應該怎麼做?

W3C 制定了 Cross-Origin Resource Sharing 的規範,簡稱 CORS(跨來源資源共享),這套規範中規定,如果要允許跨來源的 HTTP 請求,Server 必須在 Response 的 Header 加上 Access-Control-Allow-Origin: *,星號就代表萬用字元,意思是任何一個 Origin 都接受。所以當瀏覽器接收到這個 Response 之後,比對目前的 Origin 符合 * 這個規則,檢驗通過,允許我們接受跨來源請求的回應。

參考資料:輕鬆理解 Ajax 與跨來源請求

三. Flask 實作 CORS

▍安裝 flask_cors 套件

pip install flask_cors

▍極簡模式

CORS 將會套用於所有 domains 和 routes,只需要寫 CORS(app),夠簡單吧!

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello!"

▍極簡模式+設定特定網域

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app, resources={r"/.*": {"origins": ["http://127.0.0.1","http://www.example.com"]}}) 

@app.route("/")
def helloWorld():
  return "Hello"

▍裝飾器

from flask import Flask
from flask_cors import cross_origin

app = Flask(__name__)

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

▍CORS + Blueprint

from flask_cors import cross_origin

api_v1 = Blueprint('API_v1', __name__)

CORS(api_v1)

@api_v1.route("/api/v1/users/")
def list_users():
    return "Hello!"

關於更詳細參數設定,可參考此篇:Flask 配置 Cors 跨域

最後~

▍回顧本篇 Flask CORS 實作,我們討論了以下內容:

  1. 什麼是同源政策?
  2. 什麼是 CORS?
  3. Flask 實作 CORS
    • 極簡模式
    • 極簡模式+設定特定網域
    • 裝飾器
    • CORS + Blueprint

關於 Flask 教學的延伸閱讀:

▍關於 Flask 教學系列目錄:

▍其他 Flask 相關教學:

那麼有關於 [Flask教學系列] 實作 Flask CORS 的介紹就到這邊告一個段落囉!有任何問題可以在以下留言~

有關 Flask 的最新文章,都會發佈在 Max 的 Facebook 粉絲專頁,如果想看最新更新,還請您按讚或是追蹤唷!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *