03月01, 2017

fetch笔记

团队里面有成员提及fetch原生的使用,但记得之前是有一些坑的。

下面简单介绍一下如何使用吧。一开始我的写法是这样的:

fetch(url, function(data){})

看来中jQuery的ajax毒很深,事实上正确的写法应该是这样的:

fetch(url).then(function(response) {
    return response.json();
}).then(function(data) {
    console.log(data);
}).catch(function(e) {
    console.log("Oops, error");
});

如果你觉得上面的写法很别扭,也可以采用async/await来书写:

async function ajaxUrl(url){
  try {
    let response = await fetch(url);
    let data = await response.json();
    console.log(data);
  } catch(e) {
    console.log("Oops, error", e);
  }
}

ajaxUrl("/ajax2")

因为现在基本上resfulAPI,所以通常ajax返回都是json对象。

当然我们在实际工作中没有那么简单,有些请求是post,可能还要传递data,甚至于修改headers。

那么可以查看fetch api 以及 这个API很“迷人”——(新的Fetch API)

给个简单的样例:

fetch("/ajax2", {
    credentials: "include",
    method: "post",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify({a: 1, b: 2})
}).then(function(response) {
    return response.json();
}).then(function(data) {
    console.log(data);
}).catch(function(e) {
    console.log("出错了");
});

timeout超时处理:issue

// Rough implementation. Untested.
function timeout(ms, promise) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      reject(new Error("timeout"))
    }, ms)
    promise.then(resolve, reject)
  })
}

timeout(1000, fetch("/hello")).then(function(response) {
  // process response
}).catch(function(error) {
  // might be a timeout error
})

abort这一块,似乎目前是无解的,相关的issue

看英文着实很累,不过了解了一个SuperAgent,倒可以学习一下。

下面来说说原生fetch的坑吧。

  • 默认不带cookie,同一个请求,用$.ajax和fetch截图如下:

jquery-ajax

fetch

可以很清晰的看到上图用jquery发起的请求有带cookie。

解决方案很简单,只需要写成这样即可:

fetch(url, {credentials: "include"})

对于参考资料里面提到的

服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。

这个我用koa2测试了一下:

router.post("/ajax2", async (ctx, next) => {
    // await new Promise((resolve) => setTimeout(resolve, 5000));
    ctx.status = 500;
    ctx.body = "内部报错";
});

会走到catch流程(也就是说会reject)的,所以可能是版本的问题吧。

参考资料

本文链接:www.my-fe.pub/post/fetch-note.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。