覺得太久沒寫的話又會忘記它的寫法。
簡述
這邊是用這支 API 來做示範。
GET
簡單來說順序一定是這樣:
- 建立 XHR 實體
- 打開要請求的 end point
- 設定拿到回應的 callback
- 發送 request 失敗的 callback
- 送出 request
1
| <button>Send request</button>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| function sendRequest(url, callback) { const request = new XMLHttpRequest() request.open('GET', url, true) request.setRequestHeader('client-id', 'xxxxxx') request.onload = () => { if (request.status >= 200 && request.status < 400) { callback(null, request.responseText) } else { callback('We reached our target server, but it returned an error') } } request.onerror = () => { callback('There was a connection error of some sort') } request.send() }
const URL = 'https://gorest.co.in/public/v1/users' const button = document.querySelector('button')
button.onclick = () => { sendRequest(URL) .then(data => console.log(JSON.parse(data))) .catch(err => console.log(err)) }
|
備註:onerror
的定義是你連 request 都沒有送出去,伺服器根本沒收到的意思。
POST
跟剛剛差不多,但要注意 POST 的資料格式:
application/json
JSON
application/x-www-form-urlencoded
Form
這邊示範 JSON:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| function sendRequest(url) { return new Promise((resolve, reject) => { const params = { email: 'aaa123456@gmail.com', gender: 'male', name: 'Jacky', status: 'active' } const request = new XMLHttpRequest() request.open('POST', url, true) request.setRequestHeader('Content-type', 'application/json') request.setRequestHeader('Authorization', 'Bearer xxxxx') request.onload = () => { if (request.status >= 200 && request.status < 400) { resolve(request.responseText) } else { reject('We reached our target server, but it returned an error') } } request.onerror = () => { reject('There was a connection error of some sort') } request.send(JSON.stringify(params)) }) }
const URL = 'https://gorest.co.in/public/v1/users' const button = document.querySelector('button')
button.onclick = () => { sendRequest(URL) .then(data => console.log(JSON.parse(data))) .catch(err => console.log(err)) }
|
Form 表單:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| function sendRequest(url) { return new Promise((resolve, reject) => { const request = new XMLHttpRequest() request.open('POST', url, true) request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8') request.setRequestHeader('Authorization', 'Bearer xxxxx') request.onload = () => { if (request.status >= 200 && request.status < 400) { resolve(request.responseText) } else { reject('We reached our target server, but it returned an error') } } request.onerror = () => { reject('There was a connection error of some sort') } request.send('email=bbb123456@gmail.com&gender=male&name=Jacky&status=active') }) }
const URL = 'https://gorest.co.in/public/v1/users' const button = document.querySelector('button')
button.onclick = () => { sendRequest(URL) .then(data => console.log(JSON.parse(data))) .catch(err => console.log(err)) }
|
或其實也可以用 FormData
來設定資料:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| function sendRequest(url) { return new Promise((resolve, reject) => { let form = new FormData() form.append('email', 'apple123456@gmail.com') form.append('gender', 'male') form.append('name', 'yoyo') form.append('status', 'active')
const request = new XMLHttpRequest() request.open('POST', url, true) request.setRequestHeader('Authorization', 'Bearer xxxx') request.onload = () => { if (request.status >= 200 && request.status < 400) { resolve(request.responseText) } else { reject('We reached our target server, but it returned an error') } } request.onerror = () => { reject('There was a connection error of some sort') } request.send(form) }) }
const URL = 'https://gorest.co.in/public/v1/users/' const button = document.querySelector('button')
button.onclick = () => { sendRequest(URL) .then(data => console.log(JSON.parse(data))) .catch(err => console.log(err)) }
|
備註:我這邊實測會拿到 422
(POST 內容不對)錯誤,但我確認過格式沒錯呀。總之呢,知道能這樣用就好。
補充:為什麼會失敗?
因為這一段:
1
| request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
|
如果要用 FormData
來包裝表單,xhr 會自己幫你設定正確的 Content-type
,但如果我們自己又加上 header 的話會把原本的給覆寫掉,所以只要拿掉那一段就 OK 了。