震惊 一文入门AJAX!!!

43 阅读5分钟

AJAX

AJAX 主要用于避免大量刷新页面,请求重复数据,通过AJAX可以不重载整个页面,只需要拿到自己希望渲染的部分数据即可

数据一般由后台服务器提供,也可以是本地文件

注意: 由于ajax请求时,不再需要返回整个页面,所以,这里只需要提供数据的一方以json等格式返回所需数据即可

Json

  • 什么是Json

这是一种轻量级的数据交换格式,具备简洁和清晰的层次结构

目前几乎所有的编程语言,都支持内置的数据类型与json的互相转换,所以在实际的前后端开发过程中

前端工程师拿到的数据都是后端工程师处理好的json格式数据,前端工程师除了写好页面,还需要把这些json解析并渲染到页面

  • Json对应的Js
Json描述Js描述
[]列表Array数组
{}字典Object对象
""字符串String字符串
  • 一个json格式的数据
{
    "account": "admin",
    "password":"123456"
}
  • Js如何解析Json
JSON.parse(str)
  • Js如何封装Json
var data = {
    "account": "admin",
    "password": "123456"
}
json = JSON.stringify(data)

Http

在了解学习xhr时,我们要对http协议具有基本的了解

HTTP协议

http协议为超文本传输协议,直白来说,就是用以传输所编写好网页的tcp协议,而tcp协议可以理解为传输二进制流数据的一种方式

http协议由客户端主动发起请求,服务端返回响应数据

请求

一次网页的打开,通过一次请求一次响应构成

请求方式

在传输的方式上,也分为了主要GETPOST等多种请求方式,现在只讨论GETPOST

其中GET请求非常常见,普通的浏览网页行为都是GET请求,也就是当输入连接在浏览器紧接着敲击键盘上的回车时

POST常用在表单提交过程,比如用户的登录、注册这样的认证行为,起始就是一次POST请求,POST请求也被理解为提交数据的请求方式

当然,不管是GET还是POST,一次请求,就会带来一次响应,都是可以获取到数据的

请求解释
GET获取服务端数据;
POST向服务端提交数据;
PUT向服务端上传数据;
DELETE删除服务端通过Request-URL所标示的资源;
TRACE测试服务端是否可以接收到Request请求;
CONNECT以管道方式连接代理服务器;
OPTIONS返回服务器所支持的其他HTTP请求方法;
HEAD与GET方法类似,但不返回服务器响应时的消息体;
请求头

我们看到的请求头,就是当我们通过浏览器访问一个URL时,会向服务器发送的,我们经常叫这个为Request Headers(请求头)

在请求头中,维护了很多字段信息,这些常见的HTTP请求头中响应字段的详细解释如下

参考地址:en.wikipedia.org/wiki/List_o…

通过这些头部字段的标识,可以让服务器清晰认识到自己应该给客户端提供的数据

Accept: text/html指定客户端支持接收的数据类型(MIME类型)。
Accept-Charset: utf-8指定客户端可接受的字符集,缺省表示任何字符集都可以接受;
Accept-Encoding: gzip, deflate指定客户端支持的Web服务器返回内容压缩编码类型。
Accept-Language: zh-CN指定客户端可以接受的语言;
Authorization:Basic xxx=HTTP认证的权限;
Cache-Control: no-cache指定所有缓存机制必须遵从的指令;
Connection: keep-alive表示是否需要持久连接(HTTP1.1协议中默认进行持久连接);
Content-Length: 123请求的内容长度;
Content-Type: text/html用于在post及put时请求的媒体类型;
Cookie: $XXX保存在该请求域名下的COOKIE值信息,常用于表示用户的历史访问记录;
Date: Tue, 15 Nov请求发送的日期时间;
Referer: …访问到这个站点之前的地址,用来指定访问从何处而来;
User-Agent: …指定当前访问者的用户信息,经常为一些浏览器、操作系统属性;

响应

在http协议中,有很多传输数据的类型,被称作MIME格式,比如image/png专门用来标记描述被传输的数据为png格式的图片

状态码

http协议通过状态码标识此次请求是否成功或失败,失败了又是因为啥

状态码状态码英文标示意义
200OK客户端的请求服务端正常完成;
301Moved Permanently客户端请求的资源已被永久移动到新的URL;
302Found客户顿请求的资源被临时移动,客户端继续使用原有URL;常用于三方登录之后的跳转;
400Bad Request客户端的请求语法错误,或无法解析请求;
401Unauthorized请求需要经过身份验证;
403Forbidden服务端直接拒绝客户端的请求;
404Not Found客户端请求的资源找不到;
405Method Not Allowed客户端请求的方式不被允许;
500Internal Server Error服务端内部错误; 可能是因为Web服务配置文件读取错误 也可能是因为用户权限等等问题导致…
502Bad Geteway服务端内部错误; 服务端错误的网关;
响应头

通过相应的头部字段,可以表示标识返回数据的类型等等格式,让浏览器或接受数据的一方更好的解析服务器的返回

Age: 775从原始服务器到代理缓存形成的时间估算(秒为单位);
Allow: GET,HEAD指定资源的有效请求行为,不允许请求则返回405;
Cache-Control: max-age=3600缓存机制,max-age参数未缓存有效时间(秒为单位);
Content-Encoding: gzip响应内容的支持的压缩编码类型
Content-Disposition: attachment; filename="fname.ext"可下载资源属性(MIME二进制格式),提供文件下载的对话框,并默认文件名为filename;
Content-Length: 348响应的数据长度;
Content-Language: en-US响应的数据语言格式;
Content-Location: /index.htm响应资源的替代地址;
Content-Type: text/html; charset=utf-8响应数据的MIME类型;
Date: Tue, 15 Nov…服务器发送响应时的日期时间;
Expires: Tue, 15 Nov…响应过期的日期时间;
Server: NginxWeb服务器名称;
Set-Cookie: username=test; Max-Age=3600;设置HTTP响应中的cookie值;

数据提交格式

在使用post方式向服务端提交数据时,主要有如下四种提交数据的类型Content-Type

  • application/x-www-form-urlencoded: 浏览器原生表单

  • multipart/form-data: 表单上传文件时

  • application/json: 前后端分离,提交复杂格式化数据时

  • text/xml: 使用XML-RPC远程调用的请求数据类型

Mock xxx

为了模拟服务器返回数据,可以采用mock.js用来模拟服务器,用以返回数据;当然如果不嫌麻烦,起始自定义假数据也可以

  • 安装
npm install mockjs

Xhr

参考地址: developer.mozilla.org/

基本流程

XMLHttpRequest是AJAX的基础,目前大多数主流浏览器都支持XMLHttpRequest的请求方式,简称XHR

  • 创建XHR对象
var xhr = new XMLHttpRequest(); // IE7+, Firefox, Chrome, Opera, Safari
var xhr = new ActiveXObject("Microsoft.XMLHTTP"); // IE6, IE5
  • 初始化请求
xhr.open(method, url, async);
// method: 用于请求的HTTP方法,大小写不敏感
// url: 请求的主体
// async: 是否异步

如果不是异步的请求方式,那么响应获取结果只需要写到send方法之后即可

但如果是异步的方式,那么获取响应结果需要单独编写回调方法onreadystatechange获取,在下面的回调部分会有

  • 设置头部

常用来设置Authorization头部,用以完成某些请求的身份认证工作

xhr.setRequestHeader(name, value)
// name: 设置头部名称,参数不包括空白、冒号或换行
// value: 参数是头部的值,参数不包括换行
  • 发送请求
xhr.send()

请求属性

  • 响应类型限定

通过该属性声明此时客户端希望得到服务端的数据类型,该属性为一个枚举类型

xhr.responseType

有如下可选设置,默认为text类型,也就是Js中的字符串

数据类型
''DOMString
arraybufferArrayBuffer对象
blobBlob对象
documentDocument对象
jsonObject对象
textDOMString

注意: responseType无法设置在一个同步请求上,给一个同步请求设置responseType会抛出一个InvalidAccessError的异常

  • 响应状态获取

获取此次相应是否已经结束,还是刚刚开始

xhr.readyState
状态状态说明
0UNSENT请求创建好之后,调用open之前
1OPENED调用open之后
2HEADERS_RECEIVED调用send之后
3LOADINGDownloading; responseText holds partial data.
4DONE整个请求结束

整个XMLHttpRequest对象的生命周期应该如下阶段: UNSENT-初始化请求-发送请求-接收数据-解析数据-DONE

  • 响应状态码获取
xhr.status
  • 响应结果获取
xhr.responseText // 获取文本类型结果
xhr.responseXML // 获取xml格式结果
xhr.response // 获取到根据响应格式responseType对应解析好的数据

response属性会根据responseType设置的类型进行解析

请求回调

当请求成功发起时,此时会有一些回调方法可以获取到服务器的响应或是请求报错

  • onload: 请求成功
xhr.onload(e){}
  • onerror: 请求出错
xhr.onerror(){}
  • ontimeout: 请求超时
xhr.ontimeout(e){}

请求回调的事件方法定义,应该都处于xhr.send之前

请求示范

异步请求

如下是一个异步的请求demo

let xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.responseType = "json"

// 请求结束
xhr.onreadystatechange = e => {
    if(xhr.readystate === 4 && xhr.status==200) {
        let res = 'response' in xhr ? xhr.response : xhr.responseText
    }
};
同步请求

如果是同步的请求,由于无法设置responseType,需要手动通过JSON.parse解析

var xhr = new XMLHttpRequest()
xhr.open("GET", "http://127.0.0.1:8000/", false)

xhr.onload = function () {
    let response = xhr.response
    let json_response = JSON.parse(response)
}
文件请求

json格式的文件也是可以请求的

window.onload = function () {
    var xhr = new XMLHttpRequest()
    url = 'xxx.json'
    xhr.open("get",url)
    xhr.onload= function(){
        let response = JSON.parse(xhr.response)
    }
    xhr.send()
}
数据提交

一般的,使用xhr提交数据可以采用jsonform-data两种方法,分别对应如下的数据初始化方法

// json
xhr.send(JSON.stringify());
// form-data
var formData = new FormData()
formData.append(key,v)
xhr.send(formData)

下面是一个提交包含文件form-data数据提交的的小例子

<input id="file" onchange="getfile()" type="file" name="" id="">
<button onclick="send()">send</button>
var file;
function getfile() { // 获取文件
    file = document.getElementById("file").files[0]
}
function send() {
    if (!file){
        return
    }
    var xhr = new XMLHttpRequest()
    var formData = new FormData()
    formData.append(key, v)
    formData.append("file", file)
    xhr.open("post", "http://127.0.0.1:8000")
    xhr.onload = function () {
        var response = xhr.response
    }
    xhr.send(formData) // 发送具有文件的表单数据
}

Ajax

jQuery库拥有完整的Ajax方法,可以在不刷新浏览器的情况下从服务器加载数据,并且使用起来比xhr更加的简单方便


请求属性

$.ajax({
    url: "http://127.0.0.1:8000",
})
参数解释
async是否为异步请求,默认为true
url请求地址
dataType预期的返回结果类型,前端会通过该属性对返回数据进行对应的解析
contentType请求时,发送的数据类型,默认为application/x-www-form-urlencoded
processData通过请求发送的数据是否转换为查询字符串,默认是true
data经常在post请求时发送的数据
error(xhr,status,error)回调方法,请求错误时调用
success(result,status,xhr)回调方法,请求成功时调用

关于contentType,遵循MIME格式,可以选择如下常用的数据格式

提交格式解释
application/x-www-form-urlencoded表单数据
multipart/form-data表单数据,常具有文件
application/jsonjson数据

关于dataType,有如下可选类型

类型选项解释
xmlxml文档
html返回html文档信息,如果包含script代码,会在渲染至dom时执行
jsonjson数据
text文本数据
local本地数据

请求回调

成功

success(result): 请求成功时调用

success: function (result,status) {
    $("p").html(result.time)
},
  • result: 服务器返回的数据,会根据dataType指定的类型尝试解析
  • status: 服务器返回的状态

失败

error(xhr, status, error): 请求错误时调用

error: function(xhr, status, error){
    if(xhr.status==404){
        console.log("路由不存在")
        return 
    }
}
  • xhr: 该对象是一个超集,包括XMLHttpRequest对象,以及更多的详细属性和信息,比如请求失败的状态码等信息;内置的属性比较重要的有如下四个,经常会在开发过程中使用,完成一些状态判断的工作

    • readyState: 当前状态,0-未初始化,1-正在载入,2-已经载入,3-数据进行交互,4-完成
    • status: 返回的HTTP状态码,比如常见的404,500等错误代码
    • statusText: 对应状态码的错误信息,比如404错误信息是not found,500是Internal Server Error
    • responseText: 服务器响应返回的文本信息
  • status: 返回的是字符串类型,表示返回的状态,根据服务器不同的错误可能返回下面这些信息

    • timeout: 超时
    • error: 错误
    • abort: 中止
    • parsererror: 解析错误
    • 还有可能返回空值
  • error:字符串类型,表示服务器抛出返回的错误信息,如果产生的是HTTP错误,那么返回的信息就是HTTP状态码对应的错误信息,比如404的Not Found,500错误的Internal Server Error

请求示范

GET

请求接口数据的一个示范

$.ajax({
    url: "http://127.0.0.1:8000",
    type: "get",
    dataType: "json",
    success: function (result) {
		...
    },
    error: function (xhr, result, error) {
        ...
    }
})

jqueryajax还支持更方便的get请求方法

$.get(url,data,success(response,status,xhr),dataType)
POST

提交json格式的数据

$.ajax({
    url: "http://127.0.0.1:8000",
    type: "post",
    dataType: "json",
    contentType: "application/json",
    data: JSON.stringify({
        "account": "123",
    }),
    success: function (result) {
        ...
    },
    error: function (xhr, result, error) {
        ...
    }
})

jqueryajax还支持更方便的post请求方法

$.post(url,data,success(data, textStatus, jqXHR),dataType)
上传文件
<input id="file" onchange="getfile()" type="file" name="" id="">
<button onclick="send()">send</button>

功能方法,在input文件输入框触发选择文件时,保留当前表单的文件对象到全局变量file

var file;
function getfile() {
    file = document.getElementById("file").files[0]
}

当点击send按钮时,提交文件及其他数据

function send() {
    var formData = new FormData()
    formData.append("file", file)
    formData.append("account", "123")
    $.ajax({
        url: "http://127.0.0.1:8000/",
        type: "post",
        dataType: "json",
        contentType: false,
        processData: false,
        data: formData,
        success: function (result) {},
        error: function (xhr, result, error) {}
    })
}

注意: 一定要加contentType: falseprocessData: false这两个配置,这是为了避开jQuery对于Content-Type的设置,让XMLHttpRequestform-data进行正确的处理

这也是因为发送文件时,文件的内容和文本的内容需要分隔开,不然服务器没有办法正常的解析文件

对于上传文件的请求,contentType=multipart/form-data是必须的

在文件的数据提交部分,会有后面有boundary以及一串字符,这是分界符,后面的一堆字符串是随机生成的,目的是防止上传文件中出现分界符导致服务器无法正确识别文件起始位置

而设置contentTypefalse是为了避免 JQuery对其操作,从而失去分界符,而使服务器不能正常解析文件

注意

在ajax上传文时,获取文件使用jquery的dom操作

那么应该

$('#health_code')[0].files[0]