Ajax,Fetch API,Server-sent event


一、Ajax是什么?

描述:Asynchronous Javascript and XML(异步的js和xml)
作用:可以通过它在浏览器中向服务器发送异步请求

优势:

  1. 无需刷新数据(页面不用刷新)
  2. 使用 异步的方式与服务器通信(不需要打断用户的操作)
  3. 可以实现根据需求读取数据,并将服务器上的一些操作转到客户端进行处理(减轻服务器负担)

劣势:

  1. ajax影响了back按钮(使用户在浏览器中无法返回上一步操作)
  2. 会产生数据暴露
  3. 对搜索引擎支持比较弱
  4. 破坏了程序的异常机制
  5. 一些手持设备不能很好的支持ajax
  6. 违背了资源定位和url的初衷(两个用户在用一个url下面看到的内容不相同)

二、XML&&Json

在远古版本常用的存储数据的方法是XML,后来逐渐被Json替代了,下面我会对两种储存方法进行秒速和对比

1. XML

描述:可拓展标记语言(例如:配置文件)
作用:用来传输和储存数据

PS:XML和HTML
HTML中都是预定义标签,而XML中没有预定义标签,全是自定义标签,用来表示一些数据

2.Json

描述:Java Script Object Notation,是一种轻量级的数据交换格式,在语法格式上与JavaScript相同(可以很容易的将json数据转化为JavaScript对象)

语法规则:

  1. 数据为 键/值 对
  2. 数据由逗号分隔
  3. 大括号保存对象
  4. 方括号保存数组
  5. 一个名称对应一个值(类似与js的对象属性)

3.为什么选择Json

理由:

  1. XML 比 JSON 更难解析。

  2. JSON 可以直接使用现有的 JavaScript 对象解析。

  3. 针对 AJAX 应用,JSON 比 XML 数据加载更快,而且更简单:

XML和json的使用:
使用 XML:

  • 获取 XML 文档
  • 使用 XML DOM 迭代循环文档
  • 接数据解析出来复制给变量

使用 JSON:

  • 获取 JSON 字符串
  • JSON.Parse 解析 JSON 字符串

三、HTTP

在使用AJAX的过程中必不可少的是需要了解HTTP的基础知识,如:HTTP请求头?HTTP状态码?HTTP请求方式?等内容

当我们使用ajax的时候实际上就是向我们的服务器发送HTTP请求,在我们使用AJAX的时候都需要遵循其规则,然后对其结果进行处理
详见:简述HTTP

四、AJAX工作原理

在这里插入图片描述

五、AJAX标准

AJAX基于英特网标准,并使用以下技术结合

  • XMLHttpRequest对象(与服务器异步交互数据)
  • JavaScript/DOM(显示/取回信息)
  • CSS(设置书样式)
  • XML(常用作数据传输的格式)

XMLHttpRequest对象:
由微软提供的用来向服务器发送HTTP请求的对象。
通过其可以可以在不刷新页面的情况下请求特定的URL,获取数据

如果通信流程需要从服务器端接收事件或者消息数据请考虑通过EventSource接口使用server-sent event。对于全双工(双向同时通信)的通信,WebSocket可能是更好的选择

六、AJAX常用API

XMLHttpRequest API

描述:在该API中发送一个HTTP请求需要创建一个XMLHttpRequest对象,打开一个URL最后发送请求,当所有这些事物完成之后,该对象会包含一些响应主题或者HTTP status的有用信息

Fetch APL

Server-sent事件

七、XMLHttpRequest使用

1.创建对象

    //1.创建对象
    const xhr = new XMLHttpRequest()

2. 初始化请求

XMLHttpRequest.open方法由以下参数

  • 参数1:method请求方式(要求使用HTTP的方法:get,post,put,delete等)
  • 参数2:url请求地址
  • 参数3:async是否异步执行(默认为true,若为falsesend方法知道收到答复前都不会返回;若为true,已完成的通知可供事物监听器使用)
  • 可选参数:参数4:user;参数5:password
    //2.初始化
    xhr.open('GET','https://api.XXX')

3. 发送请求

    //3.发送
    xhr.send()

4.处理响应结果

在AJAX请求的过程中,XMLHttpRequest.readyState 属性也会随之发生变化,当readyState属性发生更改时,将会触发readystatechange事件(该事件不会冒泡,也不会取消,属于一般事件),而一个XHR代理总是会出于下面状态其中一个:
在这里插入图片描述
当一个XMLHttpRequest请求被abort()方法取消时,其对应的readystatechange事件就不会再被触发

在我们这个例子当中我们要做的是当readyState状态变为4也就是说当ajax执行完毕的时候对其结果进行处理,其结果无非就是两中:成功 or 失败
成功则拿到它请求的值 失败则拿出来他的失败原因

 //4.处理响应结果
    xhr.onreadystatechange = function(){
      if (xhr.readyState ===4 ) {
        if (xhr.status === 200 && xhr.response) {
        //打印成功结果
          console.log(xhr.response)
        } else {
        //打印失败结果
          console.log(xhr.status)
        }
      }
    }

分析并操作responseXML属性

如果使用XMLHttpRequest来获得远程的XML文档内容,responseXML属性将会是一个由XML文档解析而来的DOM对象,这很难被操作和分析。

五种解析XML文档的方式:

  1. 使用XPath定位到文档的指定部分。
  2. 手动解析和序列化XML为字符串或对象
  3. 使用XMLSerializer把DOM树序列化成字符串或文件
  4. 当XML文档的内容是预知的时,可以使用RegExp。

PS补充:W3CXMLHttpRequest规范将HTML解析支持添加到了XMLHttpRequest这家拍卖行,现在此功能也允许web应用使用获取作为已分析DOM的HTML资源。

局限性

  • 为了阻止同步使用 ,HTML 支持在同步模式下不可用。并且只有当responseType属性以设置为document时,HTML支持才可使用。
  • 该限制可以避免再默认模式下使用旧代码检索资源的responseText时浪费事件无用地解析HTML。此外,该限制还避免了假定responseXML用于HTTP错误页的旧代码问题

处理二进制数据

利用 XMLHttpRequest 对象的 overrideMimeType() 方法

var oReq = new XMLHttpRequest()
oReq.open("GET",URL)
oReq.overrideMimeType("text/plain; charset=x-user-defined");

5.检测进度

XMLHttpRequest提供了各种请求被处理期间发生的事件以供监听。(如:定期进度通知,错误通知等)

支持DOM的progress事件检测之于XMLHttpRequest传输,这些事件实现了ProgressEvent接口(遵循Web API的进度事件规范)

  • progress(en-US):检索的数据发生了变化
  • load(en-US):传输完成,所有数据保存再response中(使用loadend事件可以侦测搭配所有的三种加载结束条件(abort,load,error))

具体使用方法:MDN使用XMLHttoRequest

6. 提交表单和上传文件

方式:

  1. AJAX(优点:灵活;缺点:复杂)
  2. FormData API(优点:简单快捷;缺点:被收集的数据无法使用JSON.stringify()转换为一个JSON字符串)

只使用XMLHttpRequest

适用环境:不用FormData API 也不需要使用FileReader API(上传文件I)

提交方法:

  • 使用 POST 方法,并将 enctype 属性设置为 application/x-www-form-urlencoded (默认)
  • 使用 POST 方法,并将 enctype 属性设置为 text/plain
  • 使用 POST 方法,并将 enctype 属性设置为 multipart/form-data
  • 使用 GET 方法(这种情况下 enctype 属性会被忽略)

PS:enctype为编码类型

使用 FormData 对象

FormData 构造函数能使你编译一个键/值对的集合,然后使用 XMLHttpRequest 发送出去。

其主要用于发送表格数据,但是也能被单独用来传输表格中用户指定的数据

传输的数据格式和表格使用的submit()方法发送的数据格式一致

7.跨站的XMLHttpRquest

只要服务器端的配置允许您从您的web应用发送请求,就可以使用XMLHttpRequest。否则会抛出异常(INVALID_ACCESS_ERR 无效访问)

PS:如果想详细了解,强烈推荐去看这篇文章跨源资源共享(CORS)

8. 绕过缓存

通常缓存中由相应的内容时,XMLHttpRequest会尝试从缓存中读取内容

绕过缓存方法
方法1:

var req = new XMLHttpRequest();
req.open('GET', url, false);
req.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
req.send(null);

方法2:
给URL添加时间戳

http://foo.com/bar.html -> http://foo.com/bar.html?12345
http://foo.com/bar.html?foobar=baz -> http://foo.com/bar.html?foobar=baz&12345

本地缓存的都是以URL作为索引,这样可以使每个请求都是唯一的,这样就可以绕开缓存

方法3:
自动更改缓存

var oReq = new XMLHttpRequest();

oReq.open("GET", url + ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime());
oReq.send(null);

9.安全性

要启用跨站脚本,推荐的做法是对 XMLHttpRequest 的响应使用 the Access-Control-Allow-Origin 的 HTTP 头。

10.XMLHttpRequests 被停止

描述:当XMLHttpRequest收到status-0和statusTest=null的返回时,这意味着请求无法执行。一个可能导致的原因是当XMLHttpRequest origin改变时,XMLHttp执行open()。

说白了就是这边的窗口创建了一个XMLHttpRequests,还没发送完就把发送窗口关了,另一个窗口再打开的时候,他还是发送了请求,可想而知这样肯定时得不到内容的已知会处于代理被创建的状态

避免方案:activate事件设置一个监听器,一旦窗口关闭,它的unload (en-US)事件便触发。

八、Fetch APL的使用

描述:Fetch提供了对Request和Response对象的通用定义。使之今后可以被使用到更多的应用场景中。

发送请求或者获取资源,需要使用WindowOrWorkerGlobalScope.fetch()方法。该方法再window和WorkerGlobalScope均有实现。

fetch()参数

  1. 必选参数:资源路径 / Request对象(无论是否成功,都会返回一个Promise对象)
  2. 可选参数:init(配置项对象)

fetch()和ajax的不同

  1. 当接收一个非成功的HTTP状态码(如404,500等)时,从fetch()返回的Promise不会被标记为reject
  2. fetch()不会发送跨域cookies(触发使用了credentials初始化选项)

Fetch()的使用

get

<body>
<button>点击获取图片</button>
<img>
</body>
<script>
let button = document.querySelector('button')
let img = document.querySelector('img')
button.addEventListener(('click'), () => {
  fetch('https://dog.ceo/api/breeds/image/random')
    .then(response => response.json())
    .then(data => img.src = data.message)
})
</script>

示例:
在这里插入图片描述

post

<body>
<button>点击获取图片</button>
<input type="text" name="" id="">
<img>
</body>
<script>
let button = document.querySelector('button')
let input = document.querySelector('input')
let img = document.querySelector('img')
button.addEventListener(('click'), () => {
  fetch('https://jsonplaceholder.typicode.com/users', {
    method: 'post',
    body: JSON.stringify({ name: input.value }),
    headers: {
      'Content-Type': 'application/json',
    },
  })
    .then(response => response.json())
    .then(data => console.log(data))
})
</script>

示例:
在这里插入图片描述

九、Server-sent events的使用

描述:简称SSE,由于它基于HTTP协议,所以它也像HTTP协议一样,无法做到服务器主动推送信息。
但是又一种可以变通的方法:让服务器向客户端声明,后面发送流信息。
也就是说,发送的不是一次性的数据包,而是数据流,会连续不断的发送过来,这时客户端不会关闭链接,而会一直等服务器发送新的数据流,视频播放就是这样的例子。本质上,这种通信就是以流信息发方式,完成一次用时很长的下载。

SSE作用与WebSocket作用相似,下面我会把两者都列出来进行举例。

相同处

  • 都是经历浏览器和服务器之间的通信渠道,然后向浏览器推送信息。

不同处

  • 不同的是SSE是单向通道,只能服务器向浏览器发送。
  • SSE使用HTTP协议(现有的服务器软件都支持)。WebSocket是一个独立的协议
  • SSE属于轻量级,使用简单。WebSocket协议相对复杂
  • SSE默认支持断线重连。WebSocket需要自己实现
  • SSE一般只用来传送文本,二进制数据需要编码后传送。WebSocket默认支持传送二进制数据
  • SSE支持自定义发送消息类型

服务器实现

1.数据格式

服务器向浏览器发送的SSE数据,必须是UTF-8编码的文本,具有以下HTTP头信息

//必须指定MIME类型为ebent-steam
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

每一次发送的信息都由很多个message组成,每个message之间用`\n\n``分隔。每个message内部都由若干行组成,格式:

[field]:value\n

field可以是以下值:

  • data
  • event
  • id
  • retry
    通常,服务器每隔一段时间就会向浏览器发送一个注释,以褒词链接不中不断,注释如下
// 通常用冒号开头的行表示注释
: This is a comment

案例

: this is a test stream\n\n

data: some text\n\n

data: another message\n
data: with two lines \n\n

2.data字段

描述:数据内容

data:message\n\n

若数据过长可以进行分行

// 若非最后一行则用\n结尾
data: begin message\n
// 最后一行用\n\n结尾
data: continue message\n\n

案例

data: {\n
data: "foo": "bar",\n
data: "baz", 555\n
data: }\n\n

3.id字段

描述:数据标识符(数据编号/名字)

id: msg1\n
data: message\n\n

浏览器用lastEventId属性读取这个值
若链接被中断,浏览器会发送一个HTTP头,其中包含一个特殊的Last-Event-ID头信息,该值的返回,可以帮助服务器端重新建立链接
这个头信息可以被是为一种同步的机制

4.event字段

event字段表示自定义的时间类型,默认是message事件。浏览器可以用addEventListener()监听该事件

案例

event: foo\n
data: a foo event\n\n

data: an unnamed event\n\n

event: bar\n
data: a bar event\n\n

上面创建了三条信息:

  • 第一条名字为foo,触发浏览器的foo事件
  • 第二条未命名,表示默认类型,触发message事件
  • 第三条是bar ,触发浏览器的bar事件。

5.retry字段

描述:浏览器重新链接的等待时间

retry: 10000\n

需要重新发起链接的情况:

  1. 时间间隔到期
  2. 由于网络错误导致链接出错

参考:
Ajax的优点与缺点有哪些
菜鸟教程HTTP简介
蛋老师的fetch教程
阮一峰老师的Server-Sent Events 教程

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是发财不是旺财

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值