當瀏覽器收到並儲存cookies後,在下一次的request就會將cookies跟著帶著送出去,回到Server。對於無狀態的HTTP,就可以使用這樣的方式讓Server回憶這個Request之前是誰,做到保留狀態。
同樣地接者調整前篇的程式碼片段。這次要將Server收到的Cookies直接作為Response的內容返回。先來添加需要的package:
from fastapi.requests import Request
然後添加一個endpoint--GET /cookies
,將Server收到的Cookies直接作為Response的內容返回:
@app.get('/cookies')
def cookies(request: Request):
return request.cookies
現在瀏覽 http://127.0.0.1.nip.io:8000/cookies 就可以收到傳給Server的Cookies作為JSON返回。
在你可能不知道的即時更新方案中提到過AJax技術。這個技術同樣可以從瀏覽器送出cookies。來添加一個fetch_cookies.html
的檔案:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>fetch cookies</title>
</head>
<body>
<!-- <img alt="" src="https://i.ytimg.com/vi/me4Es5Yqhxk/maxresdefault.jpg"/> -->
<style>
td, th {
border: 1px solid;
}
</style>
<table>
<thead>
<tr>
<th>key</th>
<th>val</th>
</tr>
</thead>
<tbody></tbody>
</table>
<img alt="" src="https://cdnb.artstation.com/p/assets/images/images/044/689/281/large/j-r-takodachi-render.jpg?1640848152"/>
<script type="text/javascript">
window.addEventListener('load', async () => {
let response = await fetch('/cookies', { credentials: 'include' });
let cookies = await response.json();
let tbody = document.querySelector('tbody');
tbody.innerHTML = '';
for(let key in cookies) {
let val = cookies[key];
tbody.innerHTML += `<tr>
<td>${key}</td>
<td>${val}</td>
</tr>`;
}
});
</script>
</body>
</html>
其中特別看到JavaScript的部分,fetch()
的options
添加了一個credentials
其值為'include'
,這就會將cookie從瀏覽器隨同request發送到server。
let response = await fetch('/cookies', { credentials: 'include' });
然後用同樣FileResponse
的方式提供這個頁面:
@app.get('/fetch_cookies.html')
def fetchCookies():
return FileResponse('fetch_cookies.html')
瀏覽 http://127.0.0.1.nip.io:8000/fetch_cookies.html ,然後等待一下fetch()
完成,就可以看到畫面以表格呈現傳遞給Server的Cookies內容,內容可能像是:
key | val |
---|---|
only | xyz |
sendto326-1 | xyz |
sendto326-2 | xyz |
name | takodachi |
like | cookie |
不過有一些cookie只能透過HTTP傳遞,不能透過JavaScript存取、修改並發送(不過AJax同樣會作為Header的一部分發出去,只是因為存取不了,無法作為body
送出)。可以透過添加HTTPOnly
設定。再來添加一點程式碼:
@app.get('/index7.html')
def index7():
response = FileResponse('index.html')
max_age = 86400 # 1 day * 24 hour * 60 min * 60 sec
response.set_cookie('HTTP', 'YES', max_age=max_age, httponly=True)
return response
在瀏覽 http://127.0.0.1.nip.io:8000/index7.html 看看。不過會發現HTTP
並沒有出現在畫面上。
本文同時發表於我的隨筆