0

0

XML Http Request最新替代技术—— Fetch

黄舟

黄舟

发布时间:2017-02-25 13:58:08

|

2138人浏览过

|

来源于php中文网

原创

在 Web 应用中,JavaScript 通过 XMLHttpRequest (XHR)来执行异步请求,这是一种有效改进页面通信的技术,当我们谈及Ajax技术的时候,通常意思就是基于 XMLHttpRequest 的 Ajax。虽说 Ajax 很有用,但它不是最佳 API,它在设计上不符合职责分离原则,将输入、输出和用事件来跟踪的状态混杂在一个对象里。而且,基于事件的模型与现在 JavaScript 流行的 Promise 以及基于生成器的异步编程模型相背驰。本文将要介绍的内容则是XMLHttpRequest 的最新替代技术—— Fetch API, 它是 W3C 的正式标准。

兼容性

在介绍之前,先看看目前主流浏览器对 Fetch API 的支持情况:

1192.jpg

Fetch 的支持目前还处于早期的阶段,在 Firefox 39 以上,和 Chrome 42 以上都被支持了。

如果你现在就想使用它,还可以用 Fetch Polyfil,用于支持那些还未支持 Fetch 的浏览器。

在使用 Fetch 之前,也可以对其进行功能性检测:

if(self.fetch) {
    // run my fetch request here
} else {
    // do something with 
XMLHttpRequest?
}

简单的fetching示例

在 Fetch API 中,最常用的就是 fetch() 函数。它接收一个URL参数,返回一个 promise 来处理 response。response 是一个 Response 对象:

fetch("/data.json").then(function(res) 
{
  // res instanceof Response == 
true.
  if (res.ok) {
    res.json().then(function(data) {
      console.log(data.entries);
    });
  } else {
    console.log("Looks like the response wasn't 
perfect, got status", res.status);
  }
}, function(e) {
  console.log("Fetch failed!", e);
});

fetch() 接受第二个可选参数,一个可以控制不同配置的 init 对象。如果是提交一个 POST 请求,代码如下:

fetch("http://www.example.org/submit.php", 
{
  method: "POST",
  headers: {
    "Content-Type": 
"application/x-www-form-urlencoded"
  },
  body: 
"firstName=Nikhil&favColor=blue&password=easytoguess"
}).then(function(res) {
  if (res.ok) {
    //res.ok用于检测请求是否成功
    console.log("Perfect! Your settings are 
saved.");
  } else if (res.status == 401) {
    console.log("Oops! You are not 
authorized.");
  }
}, function(e) {
  console.log("Error submitting 
form!");
});

如果遇到网络故障,fetch() promise 将会 reject,带上一个 TypeError 对象。想要精确的判断 fetch() 是否成功,需要包含 promise resolved 的情况,此时再判断 Response.ok 是不是为 true。

Fetch 实现了四个接口:GlobalFetch、Headers、Request 和 Response。GloabaFetch 就只包含了一个 fetch 方法用于获取网络资源,其它三个直接对应了相应的 HTTP 概念。此外,在 request/reponse 中,还混淆了 Body。

Headers

Headers 接口允许定义 HTTP 的请求头(Request.headers)和响应头(Response.headers)。一个 Headers 对象是一个简单的多名值对:

var content = "Hello World";
var myHeaders = new Headers();
myHeaders.append("Content-Type", 
"text/plain");
myHeaders.append("Content-Length", 
content.length.toString());
myHeaders.append("X-Custom-Header", 
"ProcessThisImmediately");

也可以传一个多维数组或者对象字面量:

myHeaders = new Headers({
  "Content-Type": "text/plain",
  "Content-Length": 
content.length.toString(),
  "X-Custom-Header": 
"ProcessThisImmediately",
});

此外,Headers 接口提供了 set ,delete 等 API 用于检索其内容:

console.log(reqHeaders.has("Content-Type")); // 
true
console.log(reqHeaders.has("Set-Cookie")); // 
false
reqHeaders.set("Content-Type", 
"text/html");
reqHeaders.append("X-Custom-Header", 
"AnotherValue");
console.log(reqHeaders.get("Content-Length")); 
// 11
console.log(reqHeaders.getAll("X-Custom-Header")); // 
["ProcessThisImmediately", "AnotherValue"]
reqHeaders.delete("X-Custom-Header");
console.log(reqHeaders.getAll("X-Custom-Header")); // 
[]

虽然有些操作仅在 ServiceWorkers 中使用,但相对于 XHR,其本身提供了非常方便的操作 Headers 的 API。

出于安全原因,有些 header 字段的设置仅能通过 User Agent 实现,不能通过编程设置:请求头禁置字段 和 响应头禁置字段。

如果使用了一个不合法的 HTTP Header 属性名或者写入一个不可写的属性,Headers 的方法通常都抛出 TypeError 异常:

var myResponse = Response.error();
try {
  myResponse.headers.set("Origin", 
"http://mybank.com");
} catch(e) {
  console.log("Cannot pretend to be a 
bank!");
}

最佳实践是在使用之前检查 content type 是否正确,比如:

fetch(myRequest).then(function(response) 
{
  if(response.headers.get("content-type") === 
"application/json") {
    return response.json().then(function(json) 
{
      // process your JSON further
    });
  } else {
    console.log("Oops, we haven't got 
JSON!");
  }
});

由于 Headers 可以在 request 请求中被发送或者在 response 请求中被接收,并且规定了哪些参数是可写的,Headers 对象有一个特殊的 guard 属性。这个属性没有暴露给 Web,但是它影响到哪些内容可以在 Headers 对象中被改变。

可能的值如下:

none:默认的

玄鲸Timeline
玄鲸Timeline

一个AI驱动的历史时间线生成平台

下载

r

equest:从 request 中获得的 
headers(Request.headers)只读
request-no-cors:从不同域(Request.mode no-cors)的 
request 中获得的 headers 只读
response:从 response 中获得的 
headers(Response.headers)只读
immutable:在 ServiceWorkers 中最常用的,所有的 headers 
都只读

Request

Request 接口定义了通过HTTP请求资源的request格式,一个简单请求构造如下:

var req = new 
Request("/index.html");
console.log(req.method); // "GET"
console.log(req.url); // 
"http://example.com/index.html"
console.log(req.headers); 
//请求头

和 fetch() 一样,Request 接受第二个可选参数,一个可以控制不同配置的 init 对象:

var myHeaders = new Headers();
var myInit = { method: 'GET',
               headers: myHeaders,
               mode: 'cors',
               cache: 'default' ,
               credentials: true,
               body: "image data"};
var myRequest = new 
Request('flowers.jpg',myInit);
fetch(myRequest,myInit)
.then(function(response) {
  return response.blob();
})
.then(function(myBlob) {
  var objectURL = 
URL.createObjectURL(myBlob);
  myImage.src = objectURL;
});

mode 属性用来决定是否允许跨域请求,以及哪些response 属性可读。mode 可选的属性值:

same-origin:请求遵循同源策略

no-cors: 默认值,允许来自CDN的脚本、其他域的图片和其他一些跨域资源(前提条件是 method 只能是HEAD,GET或者POST)

cors :允许跨域,请求遵循 CROS协议

credentials 枚举属性决定了cookies 是否能跨域得到,这与 XHR 的 withCredentials 标志相同,但是只有三个值,分别是omit(默认),same-origin以及include。

Response

Response 实例是在 fentch() 处理完 promises 之后返回的,它的实例也可用通过 JavaScript 来创建, 但只有在 ServiceWorkers 中才真正有用。当使用 respondWith() 方法并提供了一个自定义的response来接受request时:

 var myBody = new Blob();
addEventListener('fetch', function(event) 
{
  event.respondWith(new Response(myBody, 
{
    headers: { "Content-Type" : "text/plain" 
}
  });
});

Response() 构造方法接受两个可选参数—response的数据体和一个初始化对象(与 Request() 所接受的init参数类似.)

最常见的response属性有:

Response.status — 整数(默认值为200) 
为response的状态码.
Response.statusText — 
字符串(默认值为OK),该值与HTTP状态码消息对应.
Response.ok — 如上所示, 
该属性是来检查response的状态是否在200-299(包括200,299)这个范围内.该属性返回一个Boolean值.
Response.headers — 响应头
Response.type — 响应类型,如:basic/ cors 
/error

Body

Request 和 Response 都实现了 Body 接口,在请求过程中,二者都会携带 Body,其可以是以下任何一种类型的实例:

ArrayBuffer
ArrayBufferView
Blob/file
URLSearchParams
FormData

此外,Request 和 Response 都为他们的body提供了以下方法,这些方法都返回一个Promise对象:

arrayBuffer()
blob()
json()
text()
formData()

 以上就是XML Http Request最新替代技术—— Fetch 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

8

2026.01.30

c++ 字符串格式化
c++ 字符串格式化

本专题整合了c++字符串格式化用法、输出技巧、实践等等内容,阅读专题下面的文章了解更多详细内容。

8

2026.01.30

java 字符串格式化
java 字符串格式化

本专题整合了java如何进行字符串格式化相关教程、使用解析、方法详解等等内容。阅读专题下面的文章了解更多详细教程。

6

2026.01.30

python 字符串格式化
python 字符串格式化

本专题整合了python字符串格式化教程、实践、方法、进阶等等相关内容,阅读专题下面的文章了解更多详细操作。

1

2026.01.30

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

20

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

17

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

18

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

3

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
XML教程
XML教程

共142课时 | 6万人学习

XQuery 教程
XQuery 教程

共12课时 | 3.8万人学习

XLink  教程
XLink 教程

共7课时 | 1.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号