發請求有哪幾種方式:
比較常規來講解
form表單來發起get或post請求,但會刷新頁面a標籤可以發get請求,但會刷新頁面img標籤可以發get請求,但只能以圖片形式來展示link標籤可以發get請求,但只能以css和favicon等形式來展示script標籤可以發get請求,但只能以腳本形式來執行
如果用 CRUD 的形式來實現:
- get
- post
- put
- delete
在
http裡,response 是字串
重新認識 Ajax
Ajax 是 Asynchronous JavaScript and XML (異步 JavaScript 和 XML)
Ajax 可以通過 JavaScript 來異步通訊 (client 和 Server 進行通訊)。Ajax 可以在不用刷新整個網頁,可以達到網頁局部更新。也就是說 client 向 server 請求獲取數據來進行網頁上更新,這樣提升用戶體驗。
傳統請求過程
client會向server發起requestserver會收到請求後,進行處理您要的東西- 處理完後,
server將會創建response - 然後
server將response給client client收到response後client刷新整個頁面來更新數據
根據上面傳統請求過程步驟,我們可以知道這是同步行為。Ajax 可以讓 browser/client 和 server 之間異步通訊。我們可以通過 JavaScript 來發起請求來向 server 獲取數據來操作網頁內容局部更新,無需重刷新整個頁面,帶來用戶體驗效果!
Ajax 優點和缺點
優點
- 減少 bandwidth,減輕
server負擔, 減少請求,按照需要數據進行請求 - 提高用戶體驗
- …
缺點:
- 對
SEO不友善 - debug 不友善
- 不支持
browserback- 問題:
ajax可以做到無刷新,沒辦法更改URL,所以browser不支持前進和後退。以分頁作為例子,當我順序點分頁123,URL完全沒有變更 (局部請求資源)。我目前在分頁3,可是我點擊後退 (上一頁),照理來說後退回到分頁2,但我只回到最初上一個網址的內容分頁1,而不是分頁2。因為ajax不能在browser保留歷史紀錄。link - 解決之一:通過 HTML5 API
history.pushState或history.replaceState來操作browser歷史紀錄和無刷新行為來改變URL。
- 問題:
- 安全性問題
- …
Ajax 與跨域
只有在同源策略情況下允許發 ajax 請求。
在非同源情況下,使用 ajax 發送請求,由於 ajax 可以讀取 response 內容,所以 browser 認為是不安全,可以發送,但 browser 不會給你響應 (會被擋)。
例子:
https://facebook.com可以向https://www.facebook.com發 ajax 請求嗎?
答案:不行
如果我想透過 ajax 跨域呢?
本來 A網站想請求 B網站內容,但他們是不同域,造成無法請求響應。
可以用 cors 來告訴 browser (A網站)和(B網站)是朋友,A網站要 B網站內容,給他吧。
只要在後端
response header設定Access-Control-Allow-origin, 指定允許 A網站。
如果是多個不同域可以這樣設定Access-Control-Allow-origin, *。
跨域
browser 限制下不允許透過 JS 跨域,所以 ajax 是不被允許。像 browser 本身是沒有限制自己,如 form, img, script, link, a 等標籤都可以允許與 server 通訊,可以被說成跨域行為。
例子1:
form表單提交到另一個網站後,原本頁面無法取得新頁面內容,所以browser是認為安全。例子2:
script標籤裡,我們可以請求任意不同domain。我們也知道在同源策略裡只要 (協議,域名,端口) 三個不同就是跨域行為。在回顧跨域和同源策略是什麼,強逼自己記在心裡。
- 同源策略 - 協議,域名,端口 必須相同
- 跨域 - 協議,域名,端口 不相同等同於跨域行為
關於更多 CORS 請到 link
總結
雖然 ajax 真的很方便也非常安全,因為有同源策略 (Same origin policy),只有協議,域名,端口 必須相同。如果非要通過 ajax 來跨域的話,需要後端開啟允許可跨域來告訴 browser 我們是朋友。browser 會根據 response header 裡字段 Access-Control-Allow-Origin 知道你們關係。
面試題
請使用原生 JS 來發送 ajax 請求
答:let request = new XMLHttpRequest() request.open('GET', 'https://jsonplaceholder.typicode.com/todos') // 配置 request.onreadystatechange = function () { if (request.readyState === 4) { console.log('請求response完成') if (request.status >= 200) { console.log('請求成功') let string = request.responseText let data = JSON.parse(string) console.log(data) } else if (request.status >= 400) { console.log('請求失敗') } } } request.send()JSON 和 JavaScript
答:JSON不具備程式語言特性,它是數據傳輸格式。 JSON 官方
JSON 和 XML 都是數據格式,相比之下 JSON 可讀性很高,也得到大眾的使用!
-------------------------------------------
JS VS JSON
-------------------------------------------
undefined 沒有
null null
boolean boolean
function f1(){...} 沒有
{name: 'decadehew'} {"name":"decadehew"}
['a', 'b'] ["a", "b"]
'decadehew' "decadehew"
let person = {} 沒有
// ---------------------
// JS convert to JSON
// ---------------------
JSON.stringify({name: 'decadehew'}) // {"name": "decadehew"}
// -----------------------------
// JSON String convert to JS
// 符合 JSON 字串來表示 JS 的值
// -----------------------------
稍微說明:
// '"foo"' 是 JSON 字串,
// parse 會解析 JSON 字串轉換成 JS 的值(字串)。
// 你可以看符合 JSON 字串裡所表示/描述是什麼,它就是 JS 某類型的值!
//
//
// '"foo"' 表示是 JS 字串類型,
// "true" 表示是 boolean 類型,
// {} 表示是 JS 對象類型。
JSON.parse('"foo"') // 'foo'
JSON.parse('true'); // true
JSON.parse({"name": "decadehew"}) // {name: 'decadehew'}