在前端开发中,一次网络请求是无法避免的,而JS Fetch作为一种新型的网络请求API,其能够帮助开发者更加简洁、高效地完成数据请求,取代了原有的XMLHttpRequest(XHR)对象。
一、JS Fetch是什么?
JS Fetch是一个现代化的API,用于代表HTTP请求的响应,并且支持Promise API(解决了XHR对象存在的异步问题)。JS Fetch使从网络获取资源变得非常容易,可以使用XMLHttpRequest对象替代传统XHR对象,也可以通过其它 HTTP请求的工具库进行替代。
fetch('http://example.com/movies.json')
.then(response => response.json())
.then(data => console.log(data));
fetch函数用于发起请求,它返回一个Promise对象,其中Promise的resolve方法返回一个Response对象,该对象表示与服务器响应相关的信息。Response对象的body属性包含通过fetch请求获取到的BodyStream,而且可以通过使用各种解析器来解析文本数据。
二、JS Fetch的MDN文档
MDN的JS Fetch文档是学习使用JS Fetch时的最好指南之一。通过访问MDN文档,可以得到JS Fetch的基础知识及使用方式。
// 获取请求
fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});
文档中的这个例子展示了如何使用JS Fetch API从服务器获取JSON数据,而后使用console.log方法将数据打印到控制台中。其中的then方法链用于处理来自fetch函数的响应结果,并且返回一个Promise对象。
三、JS Fetch的API
fetch函数可接受多个参数,其中最重要的一个是URL参数,用于指定要获取资源的URL字符串。除此之外,JS Fetch还支持一系列内置API,例如:
- response.headers:包含响应标头的“只读”属性。
- response.ok:表示服务器是否成功响应,其值为布尔类型。
- response.status:响应状态码,它会根据错误代码返回响应。这个值在从服务器获取响应的时候非常常用,可用于判断服务器响应情况。
- response.statusText:响应状态类型的描述文本。
fetch('http://example.com/movies.json')
.then(response => {
console.log(response.headers.get('Content-Type'));
});
上述代码中,使用fetch获取资源后,获取响应的Content-Type,content-type是HTTP标头,指示在得到服务器响应的情况下接收的实体的媒体类型。
四、JS Fetch的await用法
JS Fetch支持ES7的Async/Await语法,把Promise代码变成更容易可读的同步代码。我们可以在运行fetch时等待结果:
async function getUsername() {
try {
const response = await fetch('/api/user');
const user = await response.json();
return user.name;
} catch (error) {
console.error('获取信息失败', error);
}
}
这里是一个使用async/await获取用户信息的示例。当fetch请求成功后,它将返回一个响应对象,返回的结果将是可以调用JSON()函数的BodyStream对象的异步解析。接下来,我们可以使用用户的名字返回结果。
五、JS Fetch的POST请求
在HTTP中,POST请求是一种方法,HTTP客户端用该方法向服务器发送数据。同样地,JS Fetch可以用于发送POST请求,代码如下:
fetch('/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
user: 'john-doe'
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error))
在上述代码中,我们可以看到fetch的第二个参数包含HTTP方法(这里是'POST')和用于发送与请求一起发送的数据体的附加信息。"headers"选项允许我们发送JSON响应,而"body"选项是POST请求中的数据负载。
六、JS Fetch函数
JS Fetch带有内置方法,其中包括对通过fetch请求获取文本内容(text)、JSON数据(json)以及ArrayBuffer对象等的处理方法。比如,我们可以使用如下代码来解析来自fetch请求的文本响应:
fetch('/example.txt')
.then(response => response.text())
.then(data => console.log(data))
.catch(error => console.log(error));
这里,我们使用text()方法来解析来自fetch请求的文本响应。取决于响应,text()方法会返回文本字符串。
七、JS Fetch跨域问题
JS Fetch默认会遵循‘同域数据源’限制,以限制由于跨站点资源获取而导致的数据泄露风险。但是,如果需要,我们也可以以跨域方式使用JS Fetch。
以下是一些例子:
fetch('https://api.example.com/data')
.then((response) => {
console.log(response);
})
.catch((error) => {
console.error(error);
});
上述例子中,我们使用了https://api.example.com上的API endpoint作为数据源。由于这是一个不同的域名,fetch请求将被阻止,因为它违反了“同源策略”。
如果我们尝试在此情况下进行跨域请求,则需要向请求头中添加credentials属性:
fetch('https://api.example.com/data', {
credentials: 'include'
})
.then((response) => {
console.log(response);
})
.catch((error) => {
console.error(error);
});
设置了credentials之后,fetch请求将可成功跨域。
八、JS Fetch Stream
JS Fetch Stream允许我们像流式传输一些数据一样逐步接收数据。下面是fetch().body实现HTTP/2流传输的示例:
const res = await fetch('/stream');
const reader = res.body.getReader();
if (res.body === null) return;
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log(value);
}
上述代码中的fetch()函数会返回一个Response对象,其中response.body是一个可读的流。然后,我们为流创建一个reader对象,reader对象允许我们从可读流中读取数据。
九、JS Fetch Headers
Headers对象是与请求和响应头部相关的相邻信息,该对象包含所有HTTP报头(也可以说成META数据)的集合。我们可以使用Headers对象来检查fetch请求和响应的HTTP标头:
fetch('/data')
.then(response => {
const headers = response.headers;
console.log(headers);
})
.catch(console.error);
上述代码中,我们使用了Headers对象来检查来自fetch请求的响应头。由于headers对象包含HTTP报头的集合,因此我们可以轻松地得到服务器响应的HTTP响应头信息。