JS 中的网络请求 AJAX, Fetch, WebSocket

栏目: Html5 · 发布时间: 5年前

内容简介:AJAX 是 Asynchronous JavaScript And XML 的简称,它可以让页面在不刷新的情况下从服务器获取数据。浏览器使用低版本 IE 浏览器没有

AJAX 是 Asynchronous JavaScript And XML 的简称,它可以让页面在不刷新的情况下从服务器获取数据。

XMLHttpRequest

浏览器使用 XMLHttpRequest 对象于服务器通信,它可以使用JSON,XML,HTML和text等格式发送和接收数据。

低版本 IE 浏览器没有 XMLHttpRequest 对象,但是它可以使用 ActiveXObject 对象代替。

if (window.XMLHttpRequest) { // IE7+
    XHR = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 6
    XHR = new ActiveXObject("Microsoft.XMLHTTP");
}
复制代码

创建 XHR 实例过后就可以监听该实例的状态改变事件 onreadystatechange ,它会在 XHR 实例的 readyState 的值改变时触发回调函数。

XHR.onreadystatechange = function () { }
复制代码

然后我们就可以使用 open 方法初始化一个请求和 send 方法发送 HTTP 请求。

XHR.open('GET', 'http://q.com')

// open 方法一共有 5 个参数,method, url, async, user, password 后三个可选。
// async 表示这次是否异步请求,默认是 true

XHR.send()
// send 方法接受一个可选参数 请求主体。
// 参数可以是 FormData, FormData, ArrayBuffer, Document, 序列化字符串
复制代码

如果是 post 方法,就要在 send 之前设置请求头的 Content-Type

httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

// 它接受两个参数 header 和 value
复制代码

然后我们就要处理服务器返回的数据,回到 onreadystatechange 函数。它监听 readyState 属性的变化,而它一共有 5 个值。

我们还需要关心 status 属性它也是只读属性,它是这次响应中的 HTTP 数字状态码。在请求之前和 XMLHttpRequest 出错时它为 0

responseText 属性是实际的数据,它是字符串,如果相应是 JSON 格式,需要用 JSON 的 parse 处理。

XHR.onreadystatechange = function () {
    if (XHR.readyState === 4 && XHR.status === 200) {
        console.log(JSON.parse(XHR.responseText))
    }
}
复制代码

如果服务器返回的是 XML, 我们可以用 responseXML 属性获得数据。

// 如果已指明,responseType 必须是空字符串或 "docuemnt" 
XHR.responseType = 'document';

// overrideMimeType() 用来强制解析 response 为 XML
XHR.overrideMimeType('text/xml');

// --------------

var root = XHR.responseXML.getElementsByTagName('root').item(0)
复制代码

responseType 属性是一个枚举类型的属性,返回响应数据的类型。

withCredentials 属性是一个Boolean类型,它指示了是否该使用类似cookies,authorization headers(头部授权)或者TLS客户端证书这一类资格证书来创建一个跨站点访问控制请求。

(在IE中,超时属性可能只能在调用 open() 方法之后且在调用 send() 方法之前设置)

abort 方法用来终止请求

getAllResponseHeaders 方法返回所有的响应头

getResponseHeader(name) 方法返回包含指定头文本的字符串

XMLHttpRequset 2

XMLHttpRequset 2 增加了一些新功能。比如能发送 FormData

超时时间

timeout 属性是超时时间,单位毫秒。当超时发生时他会触发 ontimeout 回调函数。

xhr.open('GET', '/server')

xhr.timeout = 2000

xhr.ontimeout = function (e) {}

xhr.send(null);
复制代码

还有 6 个进度事件。

loadstart
progress
error
abort
load
loadend

load 事件就不用 readystatechange 事件和读取 readyState 属性。

xhr.addEventListener("progress", updateProgress, false);
xhr.addEventListener("load", transferComplete, false);
xhr.addEventListener("error", transferFailed, false);
xhr.addEventListener("abort", transferCanceled, false);

function updateProgress(event) {
  if (event.lengthComputable) {
    console.log(`${event.position} / ${event.totalSize}`)
  }
}
复制代码

其中 progress 的事件对象多了三个属性。

lengthComputable
position
totalSize

跨域

同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

当前网址(http://news.a.com)和请求网址

https://news.a.com
http://news.a.com:8080
http://home.a.com

时就不是同源。

为了使 ajax 可以从不同的网址获取数据。

我们可以使用跨域资源共享(CORS)来解决问题。

在发送请求时会有个 Origin 头表示请求页面的源信息, 如果服务器返回的 Access-Control-Allow-Origin 中有相同的源信息或是 * 那么就可以跨域请求信息,请求和响应都不包含 cookie

CORS通过 Preflighted Requests 透明服务器验证机制支持使用自定义头部、get和post之外的方法,不同类型的主题内容。

这种请求已OPTIONS方法发送,下面是它发送的头信息:

Origin

Access-Control-Request-Method 请求自身使用的方法

Access-Control-Request-Headers 自定义头部信息,用逗号分隔

发送请求后,服务器来决定是否允许,服务器会发送如下信息与浏览器沟通:

Access-Control-Allow-Origin 允许的源

Access-Control-Allow-Methods 允许的方法,逗号分隔

Access-Control-Allow-Headers 允许的头部,逗号分隔

Access-Control-Allow-Max-Age Preflight请求缓存的时间(秒)

默认情况下跨域不提供cookie、HTTP认证、SSL证明,通过 withCredentials 属性设置为 true 可以指定某个请求因该发送凭据。 服务器如果接收请求会返回 Access-Control-Allow-Credentialstrue 的头信息。

还有一种方法是使用 JSONP

jsonp 方法主要是创建 script 标签来获得数据,一般通过请求后面跟?callback=fn 回掉函数来获取数据。

Fetch

Fetch 是网络请求的一个更好的替代方法。相比于 XMLHttpRequest,Fetch 写法更简单,功能更强大。

fetch('http://a.com')
  .then(function(response) {
    if (response.ok) {
        return response.json();
    }
    throw new Error('err')
  })
  .then(function(myJson) {
    console.log(myJson);
  })
  .catch(err => {
      console.log(err)
  })
复制代码

fetch 函数接受两个参数,返回一个 Promise 对象。

第一个参数是 URL 或 Request 对象。第二个参数是可选一个配置项对象。

{
    method: 'GET', // 请求方法
    headers: {
      'user-agent': 'Mozilla/4.0 MDN Example',
      'content-type': 'application/json'
    }, // 头信息
    body: JSON.stringify({data: 1}), // 请求的 body 信息,Blob, FormData 等
    mode: 'cors', // 请求的模式,cors、 no-cors 或 same-origin
    credentials: 'include', // omit、same-origin 或 include。为了在当前域名内自动发送 cookie, 必须提供这个选项
    cache: 'no-cache', // default 、 no-store 、 reload 、 no-cache 、 force-cache 或者 only-if-cached
    redirect: 'follow', // 可用的 redirect 模式: follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误), 或者 manual (手动处理重定向).
    referrer: 'no-referrer', // no-referrer、client或一个 URL。默认是 client。
    referrerPolicy: 'no-referrer', // 指定 referer HTTP头
    integrity: 'sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=', // 包括请求的  subresource integrity 值
}
复制代码

then 的回调函数接受一个 Response 对象。Response 实现了 Body(代表响应/请求的正文,允许你声明其内容类型是什么以及应该如何处理。)

它有 9 个属性。

type
url
useFinalURL
status
ok
edirected
statusText
headers
bodyUsed

8 个方法

clone
error
redirect(url, status)

Body(都返回一个 Promise 实例)

arrayBuffer
blob
formData
json
text

WebSocket

WebSockets 是一种先进的技术。它可以在用户的浏览器和服务器之间打开双工、双向通讯会话。

WebSocket 构造函数,接受两个参数,url 和 protocols(可选)。

url 以 ws://wss:// (加密)开头

protocols 是 单协议字符串或者包含协议字符串的数组。这些字符串用于指定子协议,这样单个服务器可以实现多个WebSocket子协议(例如,您可能希望一台服务器能够根据指定的协议处理不同类型的交互)protocol)。如果不指定协议字符串,则假定为空字符串。

var s = new WebSocket('ws://www.a.com/s.php') // 必须传入绝对URL,可以是任何网站
s.readyState // 0 建立连接 1 已经建立 2 正在关闭 3 连接已关闭或者没有链接成功
s.send('hello') // 发送的数据必须是纯文本
s.onopen = function (){
  console.log('成功建立连接时触发')
}
s.onerror = function () {
  console.log('发生错误,连接不能持续时')
}
s.onmessage = function (event) { // 当接收到消息时
  console.log(event.data) // 数据是纯字符
}
s.close() // 关闭连接
s.onclose = function (event) {
  /*
   * event.wasClean 是否明确的关闭 
   * event.code 服务器返回的数值状态码
   * event.reason 字符串,服务器返回的消息
   */
  console.log('连接关闭时')
}
复制代码

一共有 10 个属性

binaryType
bufferedAmount
extensions
onclose
onmessage
onopen
protocol
readyState
url

2 个方法

  1. close(code, reason) 数字状态码 可选 默认 1005和一个可选的类可读的字符串,它解释了连接关闭的原因。
  2. send(data) 向服务器发送数据(ArrayBuffer,Blob等)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

精通Git(第2版)

精通Git(第2版)

Scott Chacon、Ben Straub / 门佳、刘梓懿 / 人民邮电出版社 / 2017-9 / 89.00元

Git 仅用了几年时间就一跃成为了几乎一统商业及开源领域的版本控制系统。本书全面介绍Git 进行版本管理的基础和进阶知识。全书共10 章,内容由浅入深,展现了普通程序员和项目经理如何有效利用Git提高工作效率,掌握分支概念,灵活地将Git 用于服务器和分布式工作流,如何将开发项目迁移到Git,以及如何高效利用GitHub。一起来看看 《精通Git(第2版)》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具