Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

紧跟时尚,Fetch实践那些事 #7

Open
closertb opened this issue Oct 3, 2019 · 0 comments
Open

紧跟时尚,Fetch实践那些事 #7

closertb opened this issue Oct 3, 2019 · 0 comments

Comments

@closertb
Copy link
Owner

closertb commented Oct 3, 2019

写于:2017-07-09

今天看到关于阿里前端面试的提问,看到有一个兄弟说,阿里应该都用fecth了,怎么还在考ajax的底层实现,虽然以前读ajax已死,fetch永生文章时有了解这个知识,但闲着也是闲着,还是探索一下,才知道他好在那。
老规矩,看官方正式一点的文章,我还是推荐MDN的,读完个人理解,对比ajax,fetch的优势就是:

  • 语义化强,调用如ajax第三方库一样简洁;
  • 支持promise;

干活

来看一个简单的调用:

fetch('http://localhost:8089/StockAnalyse/BlogServlet', fetchInitOption({flag:"getList"}))
  .then(function(response){
    if(response.ok){  //避免404与500这样的响应
            return response.json();
    } else {
        console.error('服务器繁忙,请稍后再试;\r\nCode:' + response.status)
    }
  }).then(function(data){
    that.item =data;//在promise中this指向已经变为指向window对象,所以提前用that保存了this;
    that = null;
  });             

如果你用过ajax第三方库,如jquery,vue-resource,axios这些,你会发现,fetch调用方法和这些库相似性非常之大,再看option的那些可设置属性:

 method: GET/POST...
 headers: 和其他header设置一样,主要设置Content-type和自定义header;
 body: 要传递的数据
 mode: cors / no-cors / same-origin,默认为 no-cors
 credentials: omit / same-origin / include
 cache: default / no-store / reload / no-cache / force-cache / only-if-cached
 redirect: follow / error / manual
 referrer: no-referrer / client / 
 referrerPolicy: no-referrer / no-referrer-when-downgrade / origin /  origin-when-cross-origin / unsafe-url
 integrity:

用fetch遇到的新鲜事

  1. 不管是404,还是500这些错误,请求仍然有response响应,所以才有response.ok状态值的判断;
  2. 当我们使用第三方ajax库发送post请求,数据数据为js对象且设置Content-type为application/x-www-form-urlencoded,服务器都能正常响应(数据读取为request.getPrameter);但Fetch这样设置就会导致服务器500错误,原因就在于Fetch它如AJAX一样,是一个底层的API,没有封装类似的数据转换,第三方库都自带,关于post请求常用的Content-type,所以为了不修改服务器端,我在配置post默认请求头时,对发送数据乃做了一定处理,不过仅适用于简单JS对象,目的就是将对象转化为键值对的方式,代码如下:
function fetchInitOption(json){
 let res=new Array();
 for(let item in json){
   res.push(item+'='+json[item])
 }
 return {
   method:'post',
   mode:'cors',
   headers: {
       'Content-Type': 'application/x-www-form-urlencoded'
   },
   body:res.join('&')            
 };                   
} 
  1. this指向变化(这个不算fetch的坑,这是编程应注意的问题),因为我用了vue,实例中的this默认指向当前vue实例,但是当调用fetch这个方法在promise的响应的匿名函数里,this指向了window对象,所以这里需要提前用一个变量that来保持实例this的引用;

  2. 请求前的拦截,就是在请求前想在header中加入自定义请求头,如TOKEN,不过好像解决思路一样,也可以在InitOption时手动设置;

虽路无尽头,但步伐坚定(早上一杯鸡汤,美好的周末即将开始)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant