fetch api 初体验

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

背景

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
    113 引用 • 429 回帖 • 8 关注

相关帖子

欢迎来到这里!

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

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