fetch是一种替代XMLHttpRequest的网络请求API,它提供了一个简单、灵活并且具有强大功能的接口。在本文中,我们将从多个方面详细阐述fetch请求的相关知识。
一、fetch请求拦截
fetch请求可以通过拦截器来实现请求的拦截,可以在请求即将发送和响应已经获取之前拦截请求。拦截器可以帮助我们在请求发送之前更改请求参数、在请求结束之后处理响应结果。
以下是一个fetch请求拦截的示例代码:
fetch('/api/user', { method: 'GET', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } }) .then(response => { console.log(response); }) .catch(error => { console.log(error); }); function interceptor(fetchFunc) { return (url, options) => { console.log(`Intercepting request to ${url} with options`, options); return fetchFunc(url, options) .then(response => { console.log(`Intercepting response from ${url} with response`, response); return response; }) .catch(error => { console.error(`Intercepting error from ${url} with error`, error); throw error; }); }; } fetch = interceptor(fetch);在上面的代码中,我们定义了一个拦截器函数interceptor,并通过interceptor函数来对fetch方法进行拦截。在拦截器中,我们可以通过console.log方法来打印请求和响应内容。最后通过将拦截器函数返回后fetch方法调用指向了拦截器。
二、fetch请求携带cookie
默认情况下,fetch请求不会携带cookie信息。在需要携带cookie的请求中,我们需要在请求头中设置参数credentials为include。
以下是一个fetch请求携带cookie的示例代码:
fetch('/api/user', { method: 'GET', credentials: 'include', headers: { 'Content-Type': 'application/json', } }) .then(response => { console.log(response); }) .catch(error => { console.log(error); });在上面的代码中,我们通过设置credentials为include来携带cookie信息,同时也设置了请求头的Content-Type参数。
三、fetch请求如何中断
fetch请求使用Promise实现,若需要中断请求可以通过AbortController来实现。
以下是一个fetch请求中断的示例代码:
const controller = new AbortController(); const signal = controller.signal; fetch('/api/user', { method: 'GET', signal: signal, headers: { 'Content-Type': 'application/json', } }) .then(response => { console.log(response); }) .catch(error => { console.log(error); }); // 中断请求 controller.abort();在上面的代码中,我们使用AbortController来实现请求的中断,通过定义controller.signal并将其作为fetch请求的参数传入来实现中断。
四、fetch请求和ajax的区别
fetch请求与ajax有很多相似之处,但是也有不同之处:
- fetch请求使用Promise实现,ajax使用回调函数实现;
- fetch请求默认不携带cookie信息,ajax默认携带cookie信息;
- fetch请求支持跨域头,ajax需要使用jsonp实现跨域;
- fetch请求使用可读流处理文件,ajax不能直接处理文件;
- fetch请求使用状态码标记响应状态,ajax使用readyState和status标记响应状态。
五、fetch请求js文件
fetch请求可以用于获取js文件,获取到之后可以通过eval方法将文件内容解析为可执行的js代码。
以下是一个fetch请求获取js文件的示例代码:
fetch('/api/jsfile') .then(response => response.text()) .then(data => { eval(data); });在上面的代码中,我们通过fetch获取js文件,然后通过text方法将文件内容转为字符串,最后使用eval方法将获取到的js代码执行。
六、fetch请求封装
使用fetch的时候,我们经常会发现fetch的api操作没法满足我们的要求,比如fetch需要不同的headers、需要不同的parse方式等等,如果在业务代码中重复的使用fetch会让代码显得冗余,不够优雅。我们可以通过封装fetch,将复杂逻辑统一处理,让代码更为简洁优雅。
以下是一个fetch请求封装的示例代码:
const http = { get: (url, data, headers) => { return http.request(url, 'GET', data, headers); }, post: (url, data, headers) => { return http.request(url, 'POST', data, headers); }, request: async (url, method, data, headers) => { try { const response = await fetch(url, { method: method.toUpperCase(), headers: { 'Content-Type': 'application/json', ...headers }, body: JSON.stringify(data) }); const json = await response.json(); return json; } catch(error) { console.error(error); } } }; http.get('/api/user', {}, {'Authorization': 'Bearer xxx'}) .then(data => console.log(data)) .catch(error => console.error(error));在上面的代码中,我们定义了一个http对象,通过http对象的get和post方法来发送get和post请求。在http.request方法中,我们对请求进行了封装,支持自定义的headers、支持异步await等操作。
七、fetch请求跨域
fetch请求跨域需要跨域服务器设置Access-Control-Allow-Origin响应头,设置为允许请求的源地址。另一方面,由于fetch请求默认不携带cookie信息, 跨域请求需要设置credentials为include才能携带cookie。
以下是一个fetch请求跨域的示例代码:
fetch('http://cors-test.xxx.com/test.php', { method: 'GET', credentials: 'include', headers: { 'Content-Type': 'application/json', } }) .then(response => { console.log(response); }) .catch(error => { console.log(error); });在上面的代码中,我们通过fetch请求跨域服务器test.php的数据,并携带cookie信息。
八、fetch请求参数
fetch请求可以通过URLSearchParams来构建请求参数,也可以直接在URL中传递参数。
以下是一个fetch请求参数的示例代码:
const params = new URLSearchParams(); params.append('name', 'Tom'); params.append('age', 18); fetch('/api/user?' + params, { method: 'GET', headers: { 'Content-Type': 'application/json', } }) .then(response => { console.log(response); }) .catch(error => { console.log(error); });在上面的代码中,我们通过URLSearchParams来构建请求参数,然后将参数拼接在URL后面来发送请求。
九、fetch请求文件流
fetch请求可以通过ReadableStream接口来处理文件流,通过response.body获取响应的可读流数据。
以下是一个fetch请求文件流的示例代码:
fetch('/api/filestream') .then(response => { const reader = response.body.getReader(); return new ReadableStream({ start(controller) { function push() { reader.read().then(({ done, value }) => { if (done) { controller.close(); return; } controller.enqueue(value); push(); }); } push(); } }) }) .then(stream => new Response(stream)) .then(response => response.blob()) .then(blob => console.log(blob)) .catch(error => console.error(error));在上面的代码中,我们通过fetch响应的body获取到response的可读流,然后通过ReadableStream来将可读流转化为ReadableStream实例后,将其封装为Response实例,最后通过blob方法将response响应回来的文件数据转化为blob对象。
十、fetch请求api接口选取
根据要求,我们需要选取3~5个与fetch请求相关的api接口,以下是选取的接口:
- fetch:发起网络请求
- Headers:请求或响应头集合
- Response:网络请求响应结果
- Request:网络请求的信息,包含请求方法、请求地址及请求头等信息
- FetchEvent:表示FetchEvent(网络请求事件)在服务工作线程中的事件状态
以上是fetch请求相关知识的详细阐述,fetch作为一种新一代的网络请求API,它具备了强大的功能并且易于使用。熟练掌握fetch的使用,有助于我们更好地进行网络请求相关开发。希望文章对您有所帮助。