Cookie

早期的 Web 應用既不能發 AJAX 請求,又有維持狀態的需求,手動將標識狀態的 Token 放在表單或者 Query 字符串中都是很是容易出錯的方式,有問題就要解決,當時網景公司的一名員工 Lou Montulli 在 1994 年將 magic cookies 的概念應用到 Web 通信中,他的原始說明文檔描述了 Cookie 工做的基本原理,該文檔後來被歸入 RFC 2109規範(大多數瀏覽器實現的參考文檔),最終被歸入 RFC 2965html

簡單說,Cookie 就是瀏覽器(客戶端)存儲在用戶電腦上的一小段文本,每一個域名的 Cookie 最大爲 4KB。當瀏覽器要發 HTTP 請求時,會檢測是否有請求域的 Cookie,有則添加到 Request Header 中的 Cookie 字段中,瀏覽器會自動幫咱們作這些事,免去了手動操做可能致使的錯誤。前端

前端技術發展到如今,其實 Cookie 沒那麼重要,要實現相同的功能,咱們能夠在每次 Ajax 請求中注入一個標識 Token 的 Request Header,在每次請求時自動發送。java

同源限制

  • 協議相同
  • 域名相同
  • 端口相同

只有同源的網頁才能共享 Cookie,服務器能夠在設置 Cookie 的時候,指定 Cookie 的所屬域名爲一級域名,好比.example.com。nginx

這樣的話,二級域名和三級域名不用作任何設置,均可以讀取這個 Cookie。api

屬性

屬性之間由一個分號和空格隔開。跨域

expires

設置 Cookie 的過時時間,必須是 GMT 格式的時間(new Date().toGMTString() 或 new Date().toUTCString() 得到瀏覽器

expires=Thu, 25 Feb 2018 04:18:00 GMT 表示 Cookie 在 2018 年 2 月 25 日 4:18 分失效,瀏覽器會清空失效的 Cookie。安全

若是沒有設置 expires,默認有效期爲 Session,即會話 Cookie,關閉瀏覽器後清空。服務器

expires 是 http 1.0 中的屬性,在 http 1.1 中由 max-age 代替,兩種的做用同樣,只是語法不一樣。cookie

max-age 是以秒爲單位時間段,cookie失效時刻 = 建立時刻 + max-age,也就是存活多少秒。默認值爲 -1,表示瀏覽器關閉就刪除的會話 Cookie,0 表示立刻失效(刪除)。

domain

domain 域名,限制 Cookie 被髮送到哪些域,舉個例子就明白的:

假設有一個 domain 爲 baidu.com 的 Cookie。若請求的域名是 baidu.com、api.baidu.com 都會發送該 Cookie(一級域名包含二級域名)。若是請求 google.com 就不會發送這個 Cookie。

domain 的默認值爲設置該 Cookie 的網頁所在域名。

若是是跨域 XHR 請求,即便 domain 和 path 都知足 Cookie 的 domain 和 path,默認狀況下 Cookie 也不會添加到請求頭中。

domain 能夠設置爲頁面本域或父域,例如 www.baidu.com 能夠設置 www.baidu.com 和 baidu.com 這兩個域。

path

path 路徑,限制 Cookie 被髮生到哪些目錄,/ 表示全部路徑。

path 的默認值爲設置該 Cookie 的網頁所在目錄。

secure

設置 Cookie 在確保安全的請求中才會發生,如 HTTPS。默認狀況下,Cookie 不會帶 secure 選項。

httpOnly

設置 Cookie 是否能經過 javaScript 訪問,默認狀況下,Cookie 不會帶 httpOnly 選項。能夠經過 JavaScript 讀取、修改、刪除 Cookie。

跨域

從安全角度考慮,瀏覽器沒法獲取跨域的 Cookie 是不會變的,跨域攜帶 Cookie 只有兩種方法:

  • nginx 轉發到同一個域名
  • 先後臺設置 withCredentials、Access-Control-Allow-Credentials

在 Web 頁面中能夠隨意地載入跨域的圖片、視頻、樣式等資源, 但 AJAX 請求一般會被瀏覽器應用同源安全策略,禁止獲取跨域數據,以及限制發送跨域請求。雖然有多種方法利用資源標籤進行跨域,但可以進行的數據交互很是有限。 在 2014 年 W3C 發佈了 CORS Recommendation 來容許更方便的跨域資源共享。 默認狀況下瀏覽器對跨域請求不會攜帶 Cookie,但鑑於 Cookie 在身份驗證等方面的重要性, CORS 推薦使用額外的響應頭字段來容許跨域發送 Cookie。

open XMLHttpRequest以後,設置 withCredentials = true 可以讓該跨域請求攜帶 Cookie(攜帶的是目標頁面所在域的 Cookie)。

var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.withCredentials = true;
xhr.send();
複製代碼

Access-Control-Allow-Credentials

只設置客戶端固然是沒用的,還須要目標服務器接受你跨域發送的 Cookie。 不然會被瀏覽器的同源策略擋住:

服務器同時設置 Access-Control-Allow-Credentials 響應頭爲 "true", 便可容許跨域請求攜帶 Cookie。

Access-Control-Allow-Origin

除了設置 Access-Control-Allow-Credentials 以外,跨域發送 Cookie 還要求 Access-Control-Allow-Origin 不容許使用通配符 *

事實上不只不容許通配符,並且只能指定單一域名:

If the credentials flag is true and the response includes zero or more than one Access-Control-Allow-Credentials header values return fail and terminate this algorithm. –W3C Cross-Origin Resource Sharing

不然,瀏覽器仍是會阻止跨域請求。

javaScript

javaScript 能夠經過 document.cookie 讀取到 Cookie。

參考文檔

相關文章
相關標籤/搜索