Skip to main content

瀏覽器與網頁

在瀏覽器中儲存資料

在原始情況下,每一次的請求都會被當作一個新的來源,就算使用的是同一個使用者同一台電腦,然而,在瀏覽器中儲存資料,便可以讓伺服器快速地辨識你這個人,方法有Cookies、localStorage、sessionStorage及IndexedDB。cookies會被每一個請求發送,所以可能影響效能,因此現在多建議使用後面三種(又稱為Web storage API)。

Cookies

收到一個HTTP請求時,server端可以傳送一個Set -Cookie的標頭和回應,讓使用者的瀏覽器保存。使用者的瀏覽器以Cookie標頭將先前所存資料發送給server,可以設定Cookies的有限期限,沒有特別設定期限的會在瀏覽器被關閉之後就刪除,也稱為session cookie。

localStorage (最推薦)

可以透過Window.localStorage存取,儲存的方式類似key和value的形式。

  1. setItem() : Add key and value
  2. getItem()
  3. removeItem() : Remove by key
  4. clear() : Clear all
  5. key() : Pass a number to retrieve the key
<body>
<div class="outer">
<input class="text"><button class="store-btn">store</button>
<button class="remove-btn">remove</button>
<button class="clear-btn">clear</button>
</div>
<script>
//get item
const oldValue = window.localStorage.getItem('text')
document.querySelector('.text').value = oldValue
document.querySelector('.store-btn').addEventListener('click',function(){
const value = document.querySelector('.text').value
window.localStorage.setItem('text',value)
})

//remove by key
document.querySelector('.remove-btn').addEventListener('click',function(){
const value = document.querySelector('.text').value
window.localStorage.removeItem('text',value)
})

//clear all
document.querySelector('.clear-btn').addEventListener('click',function(){
const value = document.querySelector('.text').value
window.localStorage.removeItem('text',value)
})
//key
console.log(window.localStorage.key(0))
</script>
</body>

sessionStorage

和localStorage很相似,但是視窗關閉就會消失、不同分頁不能共用。

IndexedDB

跟前面做大的差異在於 : 儲存量較大、資料形式為json而非物件形式(key - value)

ref : 前端儲存之sessionStorage、localStorage、cookie和indexedDB - IT閱讀 (itread01.com)

網頁與伺服器溝通

之前用node.js是直接發request去server,但在網頁中使用JS會透過瀏覽器去發送,接收也會經過瀏覽器。

交換資料

form

帶資訊去到指定的新頁面。response直接透過瀏覽器render出來。

AJAX

Asynchronous JavaScript And XML.任何非同步跟伺服器交換資料的JS。

使用XMLHttpRequest(XHR)物件的方式來存取伺服器端的資料,可以讓你直接經由指定的 URL 擷取資料卻不用刷新整個網頁。

const request = new XMLHttpRequest()
request.onload = function(){
if(request.status >= 200 && request.status < 400){
console.log(request.responseText)
}else{
console.log('err')
}
}
request.onerror = function () {
console.log('error')
}
request.open('GET','https://reqres.in/',true)//發request到某地方,true代表非同步
request.send()

同源政策(same origin policy)

ref : 輕鬆理解 Ajax 與跨來源請求 (techbridge.cc)

瀏覽器基於安全性考量當要呼叫API的網站和你現在的網站不同源(e.g.Domain不同、http和https、port不同),一樣會發出request,但不會把拿到的response傳回JS。(相對來說用node.js想拿甚麼就拿甚麼不受限制)。

但不可能總是跟網站同個Domain,因此就有了CORS (Cross-Origin Resource Sharing)跨來源資源共享,Server需要在Response的Header中加上Access-Control-Allow-Origin: *<script><img>則不受限制

Preflight Request要發起需要夾帶資料的request時,會先多發一個預檢請求檢查此請求是否合乎規定,例如:我們可以用請求去刪除網站資料,但是不可能網站隨便就被一個路人亂搞,因此會需要先檢查用戶端的請求。

JSONP

起因於< script > 標籤不受同源政策規範

練習 : 擷取資料並顯示在網頁上

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS</title>
<style>
*{
font-size: 36px;
}
.profile{
border: 2px solid grey;
display: inline-flex;
margin-top: 20px;
align-items: center;
}
</style>
</head>
<body>
<div class="container">

</div>
<script src=""></script>
<script>
const container = document.querySelector('.container')
const request = new XMLHttpRequest()
request.addEventListener('load',function(){
if(request.status >= 200 && request.status < 400){
const response = request.responseText
const json = JSON.parse(response)
const data = json.data
for(let i=0; i<data.length; i++){
console.log(data[i])
const div = document.createElement('div')
div.classList.add('profile')
div.innerHTML=`<div class="profile__name"> ${data[i].first_name} ${data[i].last_name}</div><img class="profile__img" src=${data[i].avatar}>`
container.appendChild(div)
}
}else{
console.log(request.status,request.responseText)
}
})
request.onerror = function(){
console.log('error')
}
request.open('GET','https://reqres.in/api/users',true)
request.send()

</script>
</body>
</html>