js高级程序设计-21Ajax和Comet

21Ajax 和 Comet

Ajax 通信与格式无关,就是 XHR 来异步拉取数据,然后通过 DOM 来操作原页面。

创建 XHR 对象

一般直接new XMLHTTPRequest()就行了,为了兼容 IE7 之前的话,需要用new ActiveXObject('MSXML2.XMLHttp')来生成。//这里的里面的内容是有三种的

XHR 的用法

open 方法

第三个参数代表是否异步发送。

xhr.open("get", "example.html", false);

open 方法只是初始化,并不会发送请求,注意 AJAX 只能是同源的,如果跨域的话,是会报错滴。

send 方法

接受一个参数,是作为请求主体发送的数据,如果不需要传入数据,就得传入 null。

xhr.send(null):

响应的结果

响应数据自动填充 XHR 对象的属性,包括:

  • responseText:作为响应主体被返回的文本
  • responseXML:如果是’text/xml’或者是’application/xml’,就会包含 XML DOM 文档
  • status:可以将 status 状态码等于 200 作为成功的标志,304 代表可以从缓存拿,也是正确的
  • statusText:HTTP 状态的说明

注意 204 状态码可能会有问题

异步的监听

就是在open方法调用之前,重写下 onreadystatechange。

xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    //这里的状态有4种,一般4代表完成了
  }
};

在接收到响应之前还可以调用 abort 方法来取消异步请求。取消之后,还得对 XHR 对象进行解引用的操作

HTTP 头部信息

我们可以在 open 方法之后,send 方法之前调用setRequestHeader方法来设置成自己想要的值。

getResponseHeader方法可以得到对应的值,加个s就可以得到所有的头部信息。

GET 请求

get 请求的情况最多,一般就是将查询字符串参数追加到 URL 末尾。

最容易发生的错误是未将名称和值通过 encodeURIComponent 方法来转码。

注意所有的名值对都必须使用&分隔才行。

POST 请求

想支持 POST 的数据,就得模拟 form 表单
在 open 方法之后

xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

原来 post 和 get 方式传输的数据其实是一样的,也是一个&分隔的 string!!!

XMLHttpRequest 2 级

2 级并没有得到全部的支持

FormData

可以帮助你来将数据数据序列化,这些东西 jquery 帮我们做的太无感了

var data = new FormData();
data.append("name", "Nicholas");

超时设定

这个东西只有 IE8 支持,jquery 啥的都是用的自己的 timeout

xhr.timeout = 1000;
xhr.ontimeout = function(){...}

overrideMimeType 方法

用这个方法可以强行改写服务器端返回的数据的解析方式,这个方法必须在 send 之前调用。这个方法略不讲道理啊,和服务端好好商量下不行吗。。。

xhr.overrideMimeType("text/xml");

进度事件

主要就是下面的 6 个状态事件

load 可以用来替代 readystatechange 事件,但是实现不太一致

progress 事件

这个主要是可以监测 xhr 得到的数值的进度~~这个有些屌啊,这个东西得在 open 方法之前调用

xhr.onprogress = function(event) {
  event.lengthComputable; //得到进度信息是否可用
  event.position; //当前的位置
  event.totalsize; //总共的预期的数据
};

跨源资源共享

CORS(cross origin resource sharing)

定义了在必须访问跨源资源时,浏览器和服务器如何沟通。

思想是使用自定义的 HTTP 头部来决定请求或者响应是否成功。

在发起请求时带一个 Origin:http://www.baidu.com

然后在后端返回的时候给一个 Access-Control-Allow-Origin,里面可以是‘*’或者一个特定的网址。

如果没有或者不符合的话,浏览器就会驳回请求。

这里 IE 是推出了一个 XDR 对象,和 XHR 很类似。

而其他的浏览器则是在原生的 XHR 上做了实现。

图像 Ping

使用图像来发送请求是最简单的单项通信了,这个东西最适合来做监控或者说是打点了。因为无法得到服务器端的数据,只能发送 GET 请求

var img = new Image();
img.onload = img.onerror = function() {
  alert("done");
};
img.src = "http://www.example.com/test?name=Nicholas";

JSONP

JSONP 是通过动态加载一段 js 来做到的,就是先声明了一个 function,插入到 body 中。

把 function 的 name 交给后端,后端返回一段方法的调用,并且传入参数。

浏览器接收到的实际上就是 script,会直接调用那个申明好的方法。

Comet

这个有长轮询和短轮询和流

短轮询

浏览器定时向服务器发送请求,然后不停地刷

长轮询

浏览器向服务器发送请求,服务器保持链接的打开,等到有数据传送的时候发送数据。

浏览器接收好数据之后,再打开一个新的连接。

轮询的好处在于所有的浏览器都是支持的

就是说整个的周期只使用一个 HTTP 请求,然后服务器保持链接打开,然后周期性的发送数据,然后 xhr 的 readyState 就会周期性的变成 3 了。

如果是 XHR 实现的话,如下:

xhr.onreadystatechange = function() {
  var results;
  if (xhr.readyState == 3) {
    result = xhr.responseText.subString(received);
    received = reslult.length;
    //然后处理最新的数据
  } else if (xhr.readyState == 4) {
    //处理结束的任务
  }
};

SSE API

这个必须得是同源的,并且是个单向的连接,默认情况下,这个会保持与服务器的活动链接,如果断开了还会自动重连。

响应的 MIME 类型是 text/event-stream,是纯文本

我们也可以使用 event.close();来强行断开这个连接并且不再重连。

var source = new EventSource("tesr.php");
source.onmessage = function(event) {
  var data = event.data;
};

Web Socket

  • 在一个单独的持久链接上提供双全工,双向通信。
  • 创建后,会有 HTTP 请求发送到浏览器,取得服务器响应之后,连接会从 http 协议变成 web sockets 协议
  • 协议是自己定的,所以是 ws:www.example.com

web socket 支持情况非常差,但是没有同源策略的限制,连不连接全依靠服务器端来识别。

一旦尝试创建,会有一个 readyState 表示状态,想要关闭,可以在任何时候调用 close 方法。

一旦打开了之后,就可以来 send 任何的数据,但是只能发送纯文本,所以必须先 JSON.stringify 才行。

一旦受到消息,会触发 onmessage 方法。

还有一些方法,比如 open,eror,close 会在相应地时刻触发。

安全

CSRF

cross-site-request-forery 跨站点请求伪造

注意改变 get 变成 put,检查来源,检查 cookie 都不行

可以的解决方法:

  • 以 ssl 来访问可以通过 XHR 请求的资源
  • 每次请求都得到附带响应算法的验证码

tudo:跨源资源共享那里还有些问题。
tudo:ssl 是啥?


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 981909093@qq.com

文章标题:js高级程序设计-21Ajax和Comet

文章字数:1.8k

本文作者:泽鹿

发布时间:2019-08-28, 16:45:23

最后更新:2019-08-28, 16:45:23

原始链接:http://panyifei.github.io/2019/08/28/读书笔记/Javascript高级程序设计/21Ajax和Comet/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏