随身笔记
随身笔记

js获取数据及未来取代XMLHttpRequest——fetch对象

要使用js获取到其他网站提供的数据,我们一般的反应就是使用ajax来实现,其中ajax又是使用的是XMLHttpRequest来实现的,具体来感受下它的代码

原生ajax笔记

在封装好之前是不是觉得又点凌乱,在来感受一下原生的fetch对象。

//从服务器获取数据
fetch('http://45.32.197.68/a1.php').then(function(res) {
    if (res.ok) {
        res.json().then(function(obj) {
            console.log(obj); //这里是返回的数据
        })
    }
}, function(ex) {
    console.log('这里是失败后才回调')
});

 

 

//发送数据给服务器
fetch('http://45.32.197.68/a.php', {
 method: 'post',
 headers: {
    "Content-type": "application/x-www-form-urlencoded; charset=UTF-8",  //模拟表单提交数据给服务器
    "userToken": "100131601455909631number2"
 },
 body: JSON.stringify({}),  //要发送给服务器的数据
 referrer: "about:client",
  referrerPolicy: "no-referrer-when-downgrade",
  mode: "cors", 
  credentials: "same-origin",
  cache: "default",
  redirect: "follow",
  integrity: "",
  keepalive: false,
  signal: undefined
})
 .then(Response =>{
    return Response.json()    //text  json  blob  arrayBuffer
 })
 .then(function (data) {
      console.log('Request succeeded with JSON response', data);  //提交数据成功后的回调
 })
 .catch(function (error) {
      console.log('Request failed', error);   //失败后的回调
 });

 

1,提交 JSON 数据

const user = { name: 'John', surname: 'Smith' };

headers: {
   'Content-Type': 'application/json;charset=utf-8'
}, 
body: JSON.stringify(user)

 

2,提交表单

const form = document.querySelector('form');

const response = await fetch('/users', {
  method: 'POST',
  body: new FormData(form)
})

 

3,文件上传以及整个表单

const input = document.querySelector('input[type="file"]');

const data = new FormData();
data.append('file', input.files[0]);
data.append('user', 'foo');

fetch('/avatars', {
 method: 'POST',
 body: data
});

 

4,直接上传二进制数据

let blob = await new Promise(resolve => 
 canvasElem.toBlob(resolve, 'image/png')
);

let response = await fetch('/article/fetch/post/image', {
 method: 'POST',
 body: blob
});

 

其他介绍:

cache属性指定如何处理缓存。可能的取值如下:

default:默认值,先在缓存里面寻找匹配的请求。
no-store:直接请求远程服务器,并且不更新缓存。
reload:直接请求远程服务器,并且更新缓存。
no-cache:将服务器资源跟本地缓存进行比较,有新的版本才使用服务器资源,否则使用缓存。
force-cache:缓存优先,只有不存在缓存的情况下,才请求远程服务器。
only-if-cached:只检查缓存,如果缓存里面不存在,将返回504错误。

 

mode属性指定请求的模式。可能的取值如下:

cors:默认值,允许跨域请求。
same-origin:只允许同源请求。
no-cors:请求方法只限于 GET、POST 和 HEAD,并且只能使用有限的几个简单标头,不能添加跨域的复杂标头,相当于提交表单所能发出的请求。

 

credentials属性指定是否发送 Cookie。可能的取值如下:

same-origin:默认值,同源请求时发送 Cookie,跨域请求时不发送。
include:不管同源请求,还是跨域请求,一律发送 Cookie。
omit:一律不发送。

跨域请求发送 Cookie,需要将credentials属性设为include。

fetch('http://another.com', {
 credentials: "include"
});

 

signal

signal属性指定一个 AbortSignal 实例,用于取消fetch()请求

 

keepalive

keepalive属性用于页面卸载时,告诉浏览器在后台保持连接,继续发送数据。

一个典型的场景就是,用户离开网页时,脚本向服务器提交一些用户行为的统计信息。这时,如果不用keepalive属性,数据可能无法发送,因为浏览器已经把页面卸载了。

window.onunload = function() {
 fetch('/analytics', {
  method: 'POST',
  body: "statistics",
  keepalive: true
 });
};

 

redirect属性指定 HTTP 跳转的处理方法。可能的取值如下:

follow:默认值,fetch()跟随 HTTP 跳转。
error:如果发生跳转,fetch()就报错。
manual:fetch()不跟随 HTTP 跳转,但是response.url属性会指向新的 URL,response.redirected属性会变为true,由开发者自己决定后续如何处理跳转。

 

integrity

属性指定一个哈希值,用于检查 HTTP 回应传回的数据是否等于这个预先设定的哈希值。

比如,下载文件时,检查文件的 SHA-256 哈希值是否相符,确保没有被篡改。

fetch('http://site.com/file', {
 integrity: 'sha256-abcdef'
});

 

referrer

属性用于设定fetch()请求的referer标头。

这个属性可以为任意字符串,也可以设为空字符串(即不发送referer标头)。

fetch('/page', {
 referrer: ''
});

 

referrerPolicy

属性用于设定Referer标头的规则。可能的取值如下:

no-referrer-when-downgrade:默认值,总是发送Referer标头,除非从 HTTPS 页面请求 HTTP 资源时不发送。
no-referrer:不发送Referer标头。
origin:Referer标头只包含域名,不包含完整的路径。
origin-when-cross-origin:同源请求Referer标头包含完整的路径,跨域请求只包含域名。
same-origin:跨域请求不发送Referer,同源请求发送。
strict-origin:Referer标头只包含域名,HTTPS 页面请求 HTTP 资源时不发送Referer标头。
strict-origin-when-cross-origin:同源请求时Referer标头包含完整路径,跨域请求时只包含域名,HTTPS 页面请求 HTTP 资源时不发送该标头。
unsafe-url:不管什么情况,总是发送Referer标头。

 

中途取消fetch()请求

let controller = new AbortController();
let signal = controller.signal;

fetch(url, {
 signal: controller.signal
});

signal.addEventListener('abort',
 () => console.log('abort!')
);

controller.abort(); // 取消

console.log(signal.aborted); // true

上面示例中,首先新建 AbortController 实例,然后发送fetch()请求,配置对象的signal属性必须指定接收 AbortController 实例发送的信号controller.signal。

controller.abort()方法用于发出取消信号。这时会触发abort事件,这个事件可以监听,也可以通过controller.signal.aborted属性判断取消信号是否已经发出。

下面是一个1秒后自动取消请求的例子。

let controller = new AbortController();
setTimeout(() => controller.abort(), 1000);

try {
 let response = await fetch('/long-operation', {
 signal: controller.signal
});
} catch(err) {
 if (err.name == 'AbortError') {
  console.log('Aborted!');
 } else {
  throw err;
 }
}

 

http://www.ruanyifeng.com/blog/2020/12/fetch-tutorial.html

 

实用案例及上传

案例demo

 

其实功能上的差不多,但fetch的优点就是代码简洁,容易维护,但一个缺点就是没有类似XMLhttprequest中的onprogress监听函数,无法显示上传进度监听。

个人推荐使用reqwest.js插件兼容性都很好,参考:https://sdeno.com/?p=6218

没有标签
首页      前端资源      js获取数据及未来取代XMLHttpRequest——fetch对象

随身笔记

js获取数据及未来取代XMLHttpRequest——fetch对象
要使用js获取到其他网站提供的数据,我们一般的反应就是使用ajax来实现,其中ajax又是使用的是XMLHttpRequest来实现的,具体来感受下它的代码 https://sdeno.com/?p=4887 在封装好…
扫描二维码继续阅读
2017-11-30