整理学习——fetch

文章目录

  • 简单说明
  • fetch(resource[, option])
    • 参数
      • resource
      • option
        • method
        • headers
        • body
        • mode
        • credentials
        • cache
        • redirect
        • referrer
        • referrerPolicy
        • integrity
        • keepalive
        • signal
  • 例子
    • 基础示例
    • Request中配置
    • fetch中配置
  • 和Ajax的区别

简单说明

fetch()函数和promise对象都是用于异步编程的。异步编程最主要的目的就是解决有可能阻塞运行的代码。将阻塞的代码在子线程进行计算运行,而不阻塞主要运行的主线程,并在运行完毕了再运行处理结果的函数。

fetch(resource[, option])

从WindowOrWorkerGlobalScope用Mixin模式 1 的fetch(input[, option])是从网络上获取资源的函数。它返回一个一旦完成就可以得到response的promise。这个promise在你的请求中会被解析为一个Response对象以供后续的then函数使用。promise对象不会拒绝HTTP错误,它只会拒绝网络错误,所以在后续的then函数中需要判断HTTP错误。
Window和WorkerGlobalScope都实现了WorkerOrGlobalScope。这意味着基本在任何场景下只要你想获取资源,都可以使用位于WorkerOrGlobalScope中的fetch()方法等。
当发生网络错误时,fetch()的promise会拒绝。比如权限问题或者其他问题。fetch的promise不会拒绝HTTP错误,即404、505这些HTTP错误。所以在开发的时候需要在then中添加对Response.ok或Response.status的判断。
fetch()方法由Content Security Policy 2的content-src指令控制,而不是由请求返回的资源所控制。

参数

resource

定义获取资源的目标地址

  • USVString3字符串,包含要获取资源的URL。一些浏览器可以接收blob:和data: 作为schemes
  • Request对象

option

配置对象,包括所有对请求的设置。以下是可选参数

method

请求的方法。GET、POST。默认是GET方法

在火狐65的环境下,Head或者Get方法无法设置Origin标头

headers

任何你想添加到你的请求的头(header),包括一个Headers对象或者包含ByteString值的USVString。

body

任何你想添加到你的请求的body(Blob、BufferSource、FormData、URLSearchParams或者一个USVString对象)

mode

请求的模式,是一个只读属性,有四种模式分别为:

  • cors:运行跨域请求,例如访问第三方的API。这些跨域请求都遵循CORS协议4,即HTTP访问控制。同时响应中应该只显示一组有限的头header,并且body部分可读。
  • no-cors:保证其方法只有HEAD、GET或POST,并且保证其headers是除了简单头部以外的headers。如果任何ServiceWorkers拦截这些请求,他们不会添加或覆盖任何headers除了简单头部。需要注意的是JavaScript不会读取Response的任何属性。这样可以确保ServiceWorkers不会影响Web语义,并防止因跨域泄露数据而导致的安全性和隐私问题。
  • same-origin:如果请求的对象非同源并且使用了该模式,那么结果显而易见会是个错误。你可以用这个模式来确认一个请求是同源的。
  • navigate:表示这是一个浏览器的页面切换请求。该请求仅在浏览器切换页面时创建,该请求应该返回HTML
credentials

只读属性,表示是否需要在跨域请求中向其他域发送cookie。有以下值:

  • omit:不发送也不接受任何cookie
  • same-origin:默认值。如果资源目标地址与响应脚本在同源时才发送验证信息(例如cookie、基本的http身份验证等)
  • include:不论是否为跨域请求,都发送验证信息(cookie、基本的HTTP身份验证等)
    与XHR中的withCredentials很想,但是他有三个值而非两个

在旧版本浏览器中same-origin依旧是omit,比如safari 11,但是在Safari 12中已更改

cache

请求的cache模式。

  1. default:浏览器在HTTP缓存中查找匹配的请求。
    • 当满足匹配的时候,刷新并从缓存中返回请求;
    • 当满足匹配但是已经过期时,浏览器将会先服务器发送一个条件请求。如果服务器表示资源没有发生变化,那么它会从缓存中返回;否则,资源会从服务器重新下载并更新缓存。
    • 当不满足匹配的时候,浏览器会发送一个正常请求并下载资源更新缓存。
  2. no-store:浏览器不会第一时间去查看缓存中是否存在,而是直接向服务器请求资源。也不会在下载目标资源的时候更新缓存
  3. reload:浏览器直接向服务器请求资源,但是在下载资源的时候会更新缓存
  4. no-cache:浏览器在缓存中获取资源。
    • 如果缓存中存在对应资源,则浏览器会向服务器发送一个条件请求。如果服务器表明资源没有发生改变,对应资源将会从缓存中返回。否则资源会从服务器下载然后更新缓存
    • 如果缓存中匹配不到,那么浏览器会向服务器发送正常请求,并且下载资源更新缓存
  5. force-cache:浏览器从缓存中匹配请求。
    • 如果缓存中存在对应资源,则会向缓存中获取资源,不论是刷新过的或者是过期的
    • 如果缓存中无法匹配到,那么浏览器会向服务器发送一个正常请求,下载资源并更新缓存
  6. only-if-cached:浏览器从缓存中匹配请求。
    • 如果缓存中存在对应请求资源,则从缓存中获取资源。
    • 如果缓存中无法匹配到对应资源,浏览器将会返回一个504网关超时。
    • *这个缓存模式仅在option.mode也是Request.mode为"same-origin"时可以使用。
      当请求的redirect属性是"follow"并且请求的重定向不违反"same-origin"模式,那么将缓存也会进行重定向。
redirect

只读属性,如何处理重定向的模式。

  1. follow:自动跟随重定向
  2. error:如果重定向发生了则抛出一个错误
  3. manual:手动处理重定向
    在Chrome,默认方式为follow,但是47之前都是manual
referrer

USVString,设置或移除当前源的任何referer。通常自动设置,并包含发出请求的URL

  1. 不设置:显示完整的请求页面URL
  2. 空字符串:请求中不显示referer
  3. 字符串:修改当前页面的当前级在请求中的显示信息。比如referrer: "ref"原来页面http://localhost:8080/test,但是修改会改为http://localhost:8080/ref
referrerPolicy

告诉浏览器每种请求的一般规则。

  1. no-referrer:阻止发送任何referer头。当你想因安全原因来隐藏referer头的时候很有用。
  2. no-referrer-when-downgrade:默认值。和no-referrer很像,除了当从一个安全上下文5导航到非安全的时候会省略referer头。
  3. origin:只发送Referer的源,而不发送页面完整地址。比如:只发送www.csdn.net,而不发送www.csdn.net/100389183
  4. origin-when-cross-origin:同origin,将完整的Referer发送到相同的源,但是除了同源以外都只发送跨源请求的部分。
  5. same-origin:向同源请求发送完整的Referer,但是跨域请求不发送Referer
  6. strict-origin:只发送源,不在HTTPS向HTTP请求中发送Referer
  7. strict-origin-when-cross-origin:同源发送完整Referer,跨域仅发送源Referer。除非是HTTPS向HTTP发送请求,这时候不发送任何Referer
  8. unsafe-url:永远在Referer中发送完整地址,不管是不是HTTPS向HTTP发送的请求
referrerPolicy To same origin To another origin HTTPS->HTTP
no-referrer - - -
no-referrer-when-downgrade full full -
origin origin origin origin
origin-when-cross-origin full origin origin
same-origin full - -
strict-origin origin origin -
strict-origin-when-cross-origin full origin -
unsafe-url full full full
integrity

包括请求的子资源完整性

keepalive

Boolean。通常在卸载文档的时候,将终止所有关联的网络请求,但是keepalive告诉浏览器即使离开页面也在后台执行请求。
但是有一点局限性:

  1. 无法发送兆字节数据:keepalive请求的正文大小被限制在64kb
    • 如果需要收集更多的数据,可以将其分批进行发送,所以在最后的unonload中发送请求时不会剩下太多的数据等待发送
    • 限制适用于当前正在进行的所有请求。所以没有办法用发100个请求每个请求64kb的包的方法来欺骗这个限制。
  2. 如果请求在onunload中被建立运行,我们无法处理服务器响应,因为此时文档已经被卸载了,函数将无法运行
    • 服务器通常会对这些请求发送空的响应,所以这个限制并不影响。
signal

一个AbortSignal对象实例。允许通过获取请求进行通讯,并且在需要时通过AbortController进行终止。

AbortSignal接口:表示信号对象,允许使用DOM请求进行通信,可以使用AbortController终止。但是是个开发中的功能,慎用。

例子

基础示例

var myImg = document.querySelector("img");
var myRequest = new Request('test.jpg');
fetch(myRequest).then((res) => {
	return res.json();
}).then((res) => {
	var objUrl = URL.createObjectURL(res);
	myImg.src = objectURL;
}).catch((err)=>{
	console.log(err.message);
});

Request中配置

var myImg = document.querySelector("img");
var myHeader = new Headers();
myHeader.append('Content-Type', 'image/jpeg');
var opt = {
	method: "GET",
	headers: myHeader,
	mode: "cors"
};
var myRequest = new Request('test.jpg', opt);
fetch(myRequest).then((res) => {
	return res.json();
}).then((res) => {
	var objUrl = URL.createObjectURL(res);
	myImg.src = objectURL;
}).catch((err)=>{
	console.log(err.message);
});

fetch中配置

var myImg = document.querySelector("img");
var myHeader = new Headers();
myHeader.append('Content-Type', 'image/jpeg');
var opt = {
	method: "GET",
	headers: myHeader,
	mode: "cors"
};
var myRequest = new Request('test.jpg');
fetch(myRequest, opt).then((res) => {
	return res.json();
}).then((res) => {
	var objUrl = URL.createObjectURL(res);
	myImg.src = objectURL;
}).catch((err)=>{
	console.log(err.message);
});

和Ajax的区别

ajax

  1. 是jQuery的一个方法,使用时需要引入jQuery
  2. 利用的是XMLHTTPRequest对象来请求数据的,是其的一个实例。
  3. 只有当状态为200和304时才会请求成功。
  4. 如果有多个连续的有依赖关系的请求,容易形成回调地狱。

而fetch,

  1. 是window的一个方法;
  2. 基于Promis实现,也可以结合async/await
  3. 请求默认不带cookie,需要设置creditials为same-origin或者include时才选择性地包含cookie
  4. 只在遭遇网络错误的时候才会发生异常。如果是HTTP错误的话会将response.ok设置为false,所以需要在后续的函数中进行判断。
  5. 所有版本的IE均不支持原生fetch
  6. 不支持abort、超时控制,使用setTimeout及Promise.reject来实现超时控制并不能阻止请求过程继续在后台运行。
  7. 无法监测请求的进度
  8. 不支持JSONP
  9. 不支持progress事件

    解决思路:传统 Ajax 已死,Fetch 永生
    解决方法:fetch使用的常见问题及解决办法

参考地址:
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetchhttps://www.zhihu.com/question/20778853
https://javascript.info/fetch-api
https://hacks.mozilla.org/2016/03/referrer-and-cache-control-apis-for-fetch/
https://developer.mozilla.org/en-US/docs/Web/API/Request/mode
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
https://developer.mozilla.org/zh-CN/docs/Web/API/Request/credentials
https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials
https://www.cnblogs.com/weiqinl/p/11279950.html
https://www.cnblogs.com/wonyun/p/fetch_polyfill_timeout_jsonp_cookie_progress.html
https://segmentfault.com/a/1190000003810652


  1. Mixin模式:JavaScript设计模式中的一种,将一个对象的全部或部分属性拷贝到另一个属性上。 ↩︎

  2. Content Sercurity Plicy:简写CSP,是一个增加的安全层,可以帮助检测和缓解某些类型的攻击,包括跨站点脚本(XSS)和数据注入攻击。 ↩︎

  3. USVString:对应字符的所有可能序列的集合。在JavaScript中返回时,映射到String。通常仅用于执行文本处理的API,需要一串字符才能进行操作。除了不允许不成对的代理代码之外,其等同于DOMString。而其中如果存在不成对的代理代码的话,将由浏览器转换为Unicode替换字符�(没打错) ↩︎

  4. CORS协议:Cross-Origin Resource Sharing,其实是一种机制,它使用额外的HTTP头来告诉浏览器,让运行在一个目标上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源回发起一个跨域HTTP请求。出于安全原因,浏览器限制从脚本内发起的跨域HTTP请求或者跨域请求可以正常进行请求。 ↩︎

  5. 安全上下文:Secure context,是一个能够确保内容能够被安全送达的(通过HTTPS/TLS)并且与潜在的非安全上下文通信时做出限制的Window或者Worker。 ↩︎

你可能感兴趣的:(JavaScript,ES6,fetch)