JS - Ajax

Ajax

Asynchronous JavaScript and XML,通过JavaScript异步通信,从服务器获取XML文档(JSON 格式数据)并从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。

  • 创建XMLHttpRequest实例
  • 发出HTTP请求
  • 接收服务器传回的数据
  • 更新网页数据

注意,AJAX只能向同源网址(协议、域名、端口都相同)发出HTTP请求,如果发出跨域请求,就会报错。

缺点同源限制

readyState

表示实例对象的当前状态,只读。

  • 0,请求未初始化,表示 XMLHttpRequest 实例已经生成,但是实例的open()方法还没有被调用。
  • 1,服务器连接已建立,表示open()方法已经调用,但是实例的send()方法还没有调用,仍然可以使用实例的setRequestHeader()方法,设定 HTTP 请求的头信息。
  • 2,请求已接受,表示实例的send()方法已经调用,并且服务器返回的头信息和状态码已经收到。
  • 3,请求处理中,表示正在接收服务器传来的数据体(body部分)。这时,如果实例的responseType属性等于text或者空字符串,responseText属性就会包含已经收到的部分信息。
  • 4,请求已完成且响应已就绪,表示服务器返回的数据已经完全接收,或者本次接收已经失败。
xhr.onreadystatechange = function(){
  /// 通信成功
  if (xhr.readyState === 4){
    /// 获取数据成功
    if (xhr.status === 200){
      console.log(xhr.responseText);
    } else {
      console.error(xhr.statusText);
    }
  }
};

status 

表示服务器回应的 HTTP 状态码。

  • 200, OK,访问正常
  • 403, Forbidden,禁止访问
  • 404, Not Found,未发现指定网址
  • 500, Internal Server Error,服务器发生错误

另外,statusText属性返回一个字符串,表示服务器发送的状态提示。

upload

主要用于追踪文件上传的进度。

该属性得到一个对象,通过该对象的onprogress上的监听函数可以得知上传的进展。

function updateProgress (evt) {
  if (evt.lengthComputable) {
    var percentComplete = evt.loaded / evt.total;
  }
}

getAllResponseHeaders()

收到服务器响应后,获取服务器发来的所有 HTTP 头信息。

返回值为字符串,每个头信息之间使用CRLF分隔(回车+换行)[\r\n]

/// 获取
var headers = xhr.getAllResponseHeaders();
/// 处理
var arr = headers.trim().split(/[\r\n]+/);
var headerMap = {};
arr.forEach(function (line) {
  var parts = line.split(': ');
  var header = parts.shift();
  var value = parts.join(': ');
  headerMap[header] = value;
});

abort()

终止已经发出的 HTTP 请求。调用方法后,readyState属性变为4,status属性变为0。 

if (xhr) {
    xhr.abort();
    xhr = null;
  }

onreadyStateChange VS onload

  • load事件表示请求成功完成,服务器传来的数据接收完毕,即只有状态码为4时才回调一次函数。
  • onreadystatechange表示只要返回的状态码发生变化就回调一次函数。

文件上传

HTML网页的<form>元素支持四种格式,向服务器发送数据:

  • POST方法,enctype=application/x-www-form-urlencoded,默认方法
  • POST方法,enctype=text/plain
  • POST方法,enctype=multipart/form-data
  • GET方法,enctype属性忽略

通常使用file控件上传文件,控件的multiple属性,标识可以一次选择多个文件。

<input type="file" id='input-file-select' name='input-file-name' multiple/>
/// 获取选中待传文件
var fileSelect = document.getElementById('input-file-select');
var files = fileSelect.files;
/// 组装FormData对象
var formData = new FormData();
files.forEach(function (file) {
  formData.append('input-file-name', file, file.name);    
});

除了使用FormData上传,也可以直接使用File API上传

var xhr = new XMLHttpRequest();
xhr.open('POST', myURL);
xhr.setRequestHeader('Content-Type', file.type);
xhr.send(file);

Ajax同源问题

除了服务器代理(浏览器请求同源服务器,再由后者请求外部服务),支持三种方法规避限制

[1]. JSONP

服务器与客户端跨源通信的常用方法,简单适用,服务端改造非常小。

缺点:只能发Get请求。但是,支持老式浏览器,可以向不支持CORS的网站请求数据。

基本思想:网页通过添加一个<script>元素,向服务器请求JSON数据,不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

[2]. WebSocket

一种使用 ws://(非加密)和 wss://(加密)作为协议前缀的通信协议,不实行同源政策。

优点:允许服务器端与客户端进行全双工(full-duplex)的通信。(HTTP仅支持客户端请求服务器)

WebSocket握手,建立在 TCP 协议之上。

[3]. CORS

跨源资源分享(Cross-Origin Resource Sharing),W3C标准, 跨源Ajax请求的 根本解决 方法。

  • 与JSONP相比,支持任何类型的请求
  • 整个CORS通信过程,浏览器自动完成

CORS请求分成两类

  • 简单请求:同表单请求
  • 非简单请求:先预检请求,不通过则提前拒绝,通过则正常请求

猜你喜欢

转载自www.cnblogs.com/wjcx-sqh/p/9193957.html
今日推荐