今天会承接昨天AJAX的课题,了解常用来处理AJAX的语法,Fetch,以及试试用fetch来实作GET、POST请求。
Fetch是一个全域window
物件,用途是送出request。当请求成功,fetch就会回传一个promise物件(状态是fulfilled),这物件内会带有response物件,里面会放有我们想抓的资料。
fetch语法:
let promise = fetch(url, [options])
options
是一堆可选的参数,例如method、header如果只有url,没有[options],就会预设这个请求的HTTP请求方法是GET。
Fetch的语法结构与Promise
非常相似,同样是用then
和catch
方法来处理成功和失败的结果:
fetch( 你想访问的url,{...一堆参数(可选)} )
.then((response) => {
//成功结果处理
})
.catch((error) => {
//错误结果处理
})
当透过fetch语法,从浏览器向服务器发出GET请求後,接下来的流程可分为两大部分。以下会用https://randomuser.me/api/
去做一个简单示范,这个API会随机产生一个人的资料。
fetch('https://randomuser.me/api/')
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(`Error: ${error}`);
})
我们可以从status
和ok
查看HTTP状态。ok
是一个布林值,如果status
是200-299,它就是true
。
虽然在阶段一回传了Response物件,但这不是我们想抓的资料,即是我们常常说的「回应内容主体(Response body)」,接下来我们需要使用方法来取得它。
Response有多种方法让我们取得资料(内容主体),包括我们常常用到的.json()
:
response.json()
:把资料转成JSON格式response.text()
:把资料转成text格式(变成纯字串)response.blob()
:把资料转成Blob物件response.formData()
:把资料转成FormData物件response.arrayBuffer()
:把资料转成二进制数组注意,只能使用一种方法来取得资料。例如我用了.json()
的方法後,不能再用另一种方法来取得资料,因为该资料已经被处理过了。
我们最常用到就是JSON格式资料,以下例子会用.json()
的方法取得资料:
fetch('https://randomuser.me/api/')
.then((response) => {
return response.json();
})
.then( (response) => {
console.log(response);
})
.catch((error) => {
console.log(`Error: ${error}`);
})
最後就取得资料了:
async/await
的写法原理是一样的,以下试试用async/await
去重写以上例子:
let getJSON = async(url) => {
let response = await fetch(url);
let JSON = await response.json();
console.log(JSON)
}
getJSON('https://randomuser.me/api/')
上面曾提及过,在fetch()
里可以有两个参数,第一个是URL,第二个是一堆参数,例如method
、header
等等。当中的header
就是Request header,即是请求表头,它用来描述我们发出的请求,例如是请求URL、请求方法。
Header这个术语是指表头,可以分为请求表头(Request header)与回应表头(Response header),它们是一堆描述这个请求或回应的资讯。我们可以用dev tool看到这些资讯:
请求表头及回应表头的格式是有规范,否则不能被服务器或浏览器接收。以下例子示范自订一个请求表头:
let response = fetch('https://randomuser.me/api/',{
headers: {
Authentication: 'secret'
}
});
但基於HTTP的准确与安全性,某些设定是不能被我们定义,只能被浏览器定义。
当我们发出POST请求时,就需要用到fetch
里的第二个参数,当中包括:
当中的request body,例如可以是:
以下用六角学院的API作例子,注册後会得到一个独立编码(UUID),这个UUID是用来组成自己的API网址时用的,另外也会提供一个API token(後台登入验证码),用来验证是否有管理员身分,并能够管理个人专属的後台。
这里会示范如果新增一笔产品资料到服务器,刚才提及uuid和token是在注册六角学院的API系统时发给我的,我把它们放在一个个的变数里,但这里就不公开了。
新增一笔产品资料的API文件:
Body Parameters就是主体参数,要写在fetch(url,{...})
的{...}
里。
以下是完整程序码:
const uuid = xxxxx
const token = xxxxx
const url = `https://course-ec-api.hexschool.io/api/${uuid}/admin/ec/product`
let headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": `Bearer ${token}`,
}
//以下是API文件中提及必写的主体参数。而以下这个产品资料是六角学院提供的。
let body = {
"title": "Abysswalker",
"category": "T-Shirts",
"content": "Its wearer, like Artorias himself, can traverse the Abyss.",
"description": "This official Dark Souls shirt was designed by Nina Matsumoto and printed on soft 100% cotton shirts by Forward. Each one comes with a bonus sticker.",
"imageUrl": ["https://images.unsplash.com/photo-1529374255404-311a2a4f1fd9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1349&q=80"]
}
fetch(url, {
method: "POST",
headers: headers,
//别忘了把主体参数转成字串,否则资料会变成[object Object],它无法被成功储存在後台
body: JSON.stringify(body)
})
.then(response => response.json())
.then(json => console.log(json));
结果:
如果我新增了3次这笔资料,後台就会有3笔资料,我们也可以用"GET"的方法去查询,六角学院提供了以下的API文件:
完整程序码:
const url = `https://course-ec-api.hexschool.io/api/${uuid}/admin/ec/products`
let headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": `Bearer ${token}`,
}
fetch(url, {
method: "GET",
headers: headers,
})
.then( (response) => response.json())
.then( (json) => console.log(json));
结果真的会显示3笔资料:
虽然之前已经学了Promise语法,学习Fetch时不会太吃力,但认真落手实作时才发觉也有一定的难度,而且当中有些术语,例如Body parametres、Header等等也没有看懂,所以除了看文章,也真的是需要实作练习一下~
AJAX 完整解说系列:新增、更新、删除(POST、PATCH、DELETE)
JAVASCRIPT.INFO
JacaScript | Fetch 让 ES6 拥有一对翅膀-基础教学
铁人赛:ES6 原生 Fetch 远端资料方法
<<: 让微软帮你管理人员 - Azure Activate Directory
最近bot的更新量蛮大,有时候会关掉bot方便更新程序码 为了让频道上的人知道目前bot的状态,决定...
⚠行前通知 先前已经学过Python但想学爬虫的人可以回来罗~ 从今天起就开始大家最期待的网页爬虫的...
Swift 语言相关的特性纪录 (算基本的东西): 可选型别: 为了避免程序运算中因所使用变数为空值...
despite all the benefits we stated yesterday, toa...
前言 参考文件: https://kubernetes.io/docs/tasks/access-a...