fetch api 初体验

本贴最后更新于 2312 天前,其中的信息可能已经斗转星移

背景

javascript 来发送 http 请求,以前用的是 jQuery 或者 XMLHttpRequest。

现在浏览器已经支持 fetch api 了。

所以需要补补 fetch 的课。

语法

用法

fetch 长下面这个样子

fetch(...).then(fun2) .then(fun3) //各依赖有序执行 ..... .catch(fun)

语法

fetch(url, options).then(function(response) { // handle HTTP response }, function(error) { // handle network error })

初体验

准备数据文件

为了避免 CORS 跨域问题,在 nodejs 上先自己准备一个 data.json 文件,内容如下:

[{ "time": "2018-11-24 00:00:25", "timestamp": 1542988825 }, { "time": "2018-11-24 00:01:25", "timestamp": 1542988885 }, { "time": "2018-11-24 00:02:25", "timestamp": 1542988945 }, { "time": "2018-11-24 00:03:25", "timestamp": 1542989005 }, { "time": "2018-11-24 00:04:25", "timestamp": 1542989065 }, { "time": "2018-11-24 00:05:25", "timestamp": 1542989125 }, { "time": "2018-11-24 00:06:25", "timestamp": 1542989185 }, { "time": "2018-11-24 00:07:25", "timestamp": 1542989245 }, { "time": "2018-11-24 00:08:25", "timestamp": 1542989305 }, { "time": "2018-11-24 00:09:25", "timestamp": 1542989365 }]

访问 http://localhost:3000/data.json, 即可以显示出来上面的数据文件,则说明准备好了。

控制台调试

打开浏览器 http://localhost:3000/data.json 页面的控制台,输入

fetch('data.json')

结果如下:

fetch('data.json') 1. Promise {} 1. __proto__: Promise 2. [[PromiseStatus]]: "resolved" 3. [[PromiseValue]]: Response 1. body: (...) 2. bodyUsed: false 3. headers: Headers {} 4. ok: true 5. redirected: false 6. status: 200 7. statusText: "OK" 8. type: "basic" 9. url: "http://localhost:3000/data.json" 10. __proto__: Response

其中 status 值为 200ok 值为 true,说明请求成功。

使用 console.log 打印结果

上面需要点开 >Promise 才能看见结果。

更方便的是,使用 console.log 来直接打印结果。

fetch('data.json').then(data => console.log(data))

效果:

Response {type: "basic", url: "http://localhost:3000/data.json", redirected: false, status: 200, ok: true, …}

只打印响应文本

上面打印出了 Response 对象,如果我们只想要响应文本呢?

fetch('data.json').then(data => data.text()).then(data => console.log(data))

效果:

[{"time":"2018-11-24 00:00:25","timestamp":1542988825},{"time":"2018-11-24 00:01:25","timestamp":1542988885},{"time":"2018-11-24 00:02:25","timestamp":1542988945},{"time":"2018-11-24 00:03:25","timestamp":1542989005},{"time":"2018-11-24 00:04:25","timestamp":1542989065},{"time":"2018-11-24 00:05:25","timestamp":1542989125},{"time":"2018-11-24 00:06:25","timestamp":1542989185},{"time":"2018-11-24 00:07:25","timestamp":1542989245},{"time":"2018-11-24 00:08:25","timestamp":1542989305},{"time":"2018-11-24 00:09:25","timestamp":1542989365}]

响应文本转成 json 格式

我们的响应文本已经准备成了 json 格式的,后期的工作也是基于 json 格式进行的。怎么样直接把 json 格式的文本直接转化成 json 格式的对象来使用呢?

fetch('data.json').then(data => data.json()).then(data => console.log(data))

效果:

(10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

异常获取

如果有异常怎么办呢?可以使用 catch 来捕获异常。下面示例会把异常打印出来。

fetch('http://data1.json').catch(e => console.error(e))

效果

VM2442:1 TypeError: Failed to fetch

主动检查结果

最佳实践方式是检查返回的结果是否正常。

下面是故意触发了一个 error,仅为了演示使用,如下:

fetch('json.json').then(response => {if (response.ok) {throw new Error("throw new error demo")} }).then(data => console.log(data)).catch(e => console.error(e))

效果

index.js:1452 Error: throw new error demo at fetch.then.response (<anonymous>:1:62)

CORS 跨域

最开始提到了因为要避免跨域,所以搞了个本地的 data.json 文件。

如何解决 CORS 跨域呢?

客户端

客户端解决:自己搭个 nodejs 服务端,在服务端将请求做一次转写

服务端

服务端解决:如果用的是 SpringBoot 的 RestController 的话,只要再增加一个 @CrossOrigin 注解即可。

效果如下:

Access-Control-Allow-Origin:*

后记

更多的内容就不写了,想深入了解的可以阅读下面的参考列表。。

参考

  • Web
    119 引用 • 433 回帖 • 8 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...