背景
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
值为 200
,ok
值为 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:*
后记
更多的内容就不写了,想深入了解的可以阅读下面的参考列表。。
参考
- fetch examples
- 使用 Fetch: 介绍了如何用 fetch 获取和发送数据
- react 中 fetch 的简单使用与跳转: 用 fetch 处理业务逻辑
- Using Fetch
- 前端 | 浅谈 fetch
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于