覺得太久沒寫的話又會忘記它的寫法。
簡述
這邊是用這支 API 來做示範。
GET
簡單來說順序一定是這樣:
- 建立 XHR 實體
- 打開要請求的 end point
- 設定拿到回應的 callback 
- 發送 request 失敗的 callback
- 送出 request
| 1
 | <button>Send request</button>
 | 
| 12
 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/jsonJSON
- application/x-www-form-urlencodedForm
這邊示範 JSON:
| 12
 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 表單:
| 12
 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 來設定資料:
| 12
 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 了。