商業,創業,美食,葡萄酒,閱讀,網路科技。
這是我的 FB粉專 以及 IG,我比較常使用 Threads,歡迎大家追蹤互動~
原文及圖片來源
https://developer.mozilla.org/zh-TW/docs/HTTP/Access_control_CORS
上面是一篇很好關於跨源資源共享 Cross-Origin Resource Sharing (以下簡稱 CORS) 的文章,我喜歡它把 request/response http header 完整列出來的部分。
https://developer.mozilla.org/zh-TW/docs/Web/Security/Same-origin_policy
目前網路協定走的是 Same-origin policy,兩個網頁 scheme, hostname, port 都相同,就算 same-origin,彼此可以存取資源 (例如圖片、CSS、JS)。scheme, hostname, port 只要有一不同,sub-domain 不同,就算 cross-origin,如需存取資源,要特別處理。
這個連結有 App Engine 如何將 Access-Control-Allow-Origin
加入 config file:
https://cloud.google.com/appengine/docs/python/config/appconfig
Google Cloud Storage 的 CORS 文件:
https://cloud.google.com/storage/docs/cross-origin
“The client (e.g., browser) checks this response header to verify that the domain in the response matches the domain specified in original request, and if these match, the request proceeds.”
所以對照 Origin 的工作是在 browser 在接到 response header 後發生,而不是在 server 端判斷。跨源資源共享 (CORS) 時,可以在 server handler 裡用程式碼判斷,將允許的 Origin 加上 Access-Control-Allow-Origin
,甚至每個 sub url 可以加上不同的 access control。以 webapp2 框架來說,語法為:
self.response.headers.add('Access-Control-Allow-Origin', your_url)
跨源存取資源分兩種,上方是 簡單請求 (simple requests)。
如果 HTTP method 不是 GET, POST, HEAD,或是非一般簡單 Content-Type。例如 HTTP method 是 PUT, DELETE,Content-Type 是 application/xml,則需要用 預檢請求 (preflighted requests)。
預檢請求會先以 HTTP OPTIONS method 詢問 server,哪些 method 允許,哪些標頭允許。收到允許後,再實際去存取資源,所以是兩段式的流程。
下面例子是一個自定義標頭 (X-PINGOTHER),和一個非簡單 Content-Type 的跨源請求,server 端的處理方式,以 webapp2 框架來說:
def options(self):
self.response.headers.add('Access-Control-Allow-Origin', your_url)
self.response.headers.add('Access-Control-Allow-Headers', 'X-PINGOTHER, Content-Type')
def post(self):
self.response.headers.add('Access-Control-Allow-Origin', your_url)
也就是藉由 OPTIONS method 先確定哪個 Origin 可以存取主機資源,哪些自定義或非簡單標頭,主機可以接受。Preflight 通過了,才能執行主要 Get / Post request。
以上藉由 Google App Engine 走一遍 跨源資源共享 的觀念和實作。也許讀者的開發環境不是 App Engine 或是 Python,可以再看一下上面 MDN 的文件,是一篇很好關於 CORS 的文章。
商業,創業,美食,葡萄酒,閱讀,網路科技。