详解AJAX(二)

103 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情

3. 原生AJAX 的基本使用 XHR

3.0 准备工作

3.0.1 安装node.js

nodejs.cn/

3.0.2 安装express(服务端框架)

www.expressjs.com.cn/

  1. 初始化环境
npm init --yes 
  1. 下载express包
npm install express --save 
  1. 编写js代码
// 1. 引入express const express = require('express');
// 2. 创建应用对象 const app = express(); 
// 3. 创建路由规则 
// request 是对请求报文的封装 
// response 是对响应报文的封装
app.get('/', (request, response) => { // 设置响应 response.send("Hello Express"); }); 
// 4. 监听端口,启动服务 app.listen(8000, () => { console.log("服务已经启动, 8000 端口监听中..."); }) 
  1. 运行js程序
node .\01express使用.js 
  1. 打开网页显示页面
  2. 调试程序可以查看请求和响应

3.0.3 安装nodemon自动重启工具

文件内容有修改自动重新启动服务 www.npmjs.com/package/nod…

安装 npm install -g nodemon 
启动服务 ndoemon server.js 

3.1 理解

  1. 使用XMLHttpRequest (XHR)对象可以与服务器交互, 也就是发送ajax 请求
  2. 前端可以获取到数据,而无需让整个的页面刷新。
  3. 这使得Web 页面可以只更新页面的局部,而不影响用户的操作。

developer.mozilla.org/zh-CN/docs/…
XMLHttpRequest,AJAX 的所有操作都是通过该对象进行的

3.2 核心对象使用步骤

3.2.1 创建XMLHttpRequest 对象

var xhr = new XMLHttpRequest();

3.2.2 设置请求信息(请求方法和url)

// 请求方式 xhr.open(method, url); 
//可以设置请求头,一般不设置 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

3.2.3 发送请求

xhr.send(body) //get请求不传 body 参数,只有post请求使用

3.2.4 接收响应(事件绑定,处理服务端返回的结果)

//xhr.responseXML 接收 xml格式 的响应数据 
//xhr.responseText 接收 文本格式 的响应数据 
xhr.onreadystatechange = function (){ 
// readyState 是 xhr对象中的属性, 表示状态 0 1 2 3 4 
if(xhr.readyState == 4 && xhr.status == 200){ var text = xhr.responseText; console.log(text); } } 

3.3 使用案例

3.3.1 GET 请求

点击返回响应信息 创建两个文件,浏览器端使用的html文件和服务器端使用的js文件 服务器端 server.js

1. 引入express const express = require('express');  
2. 创建应用对象 const app = express(); 
3. 创建路由规则 app.get('/server', (request, response) => { // 设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin', '*'); 
设置响应体 response.send("Hello Ajax"); }); 

 4. 监听服务 app.listen(8000, () => { console.log("服务已经启动, 8000 端口监听中..."); })
 启动服务 node server.js 

前端页面 html点击发送请求

# GET 请求设置请求参数

设置url参数 xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300'); 1 image.png image.png

1.3.2 POST请求

鼠标放到div中,发post请求,将响应体放在div中呈现 server.js
添加post app.post('/server', (request, response) => { 
// 设置响应头, 设置允许跨域 response.setHeader('Access-Control-Allow-Origin', '*'); 
// 设置响应体 response.send("Hello Ajax POST"); });

post.html

# 设置请求头信息

// 设置请求体内容的类型 xhr.setRequesHeader('Content-Type','application/x-www-from-urlencoded'); 
// 自定义头信息 xhr.setRequesHeader('name', 'ykyk');
1234 server.js中设置响应头允许自定义请求头 post改成all response.setHeader('Access-Control-Allow-Header','*');

3.4 json数据请求

app.all('/json-server', (request, response) => { // 设置响应头, 设置允许跨域 response.setHeader('Access-Control-Allow-Origin', '*'); 
// 设置响应头, 设置允许自定义头信息 response.setHeader('Access-Control-Allow-Headers', '*');
// 响应一个数据 const data = { name: 'atguigu' };
// 对 对象 进行 字符串 转换 let str = JSON.stringify(data) // 设置响应体
response.send(str); });

3.5 请求超时与网络异常

// 超时设置 (2秒) xhr.timeout = 2000; 
// 超时回调 xhr.ontimeout = function(){ alert('网络超时,请稍后重试') } 
// 网络异常回调 xhr.onerror = function(){ alert('网络异常,请稍后重试') } 

3.6 取消请求

// 手动取消 xhr.abort()

3.7 请求重复发送问题

3.8 解决 IE 缓存问题

问题:在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求,剩余多次请求不会在发送给浏览器而是直接加载缓存中的数据。
解决方式:浏览器的缓存是根据url 地址来记录的,所以我们只需要修改url 地址即可避免缓存问题 xhr.open("get","/testAJAX?t="+Date.now());

3.9 AJAX 请求状态 xhr.readyState

可以用来查看请求当前的状态 developer.mozilla.org/zh-CN/docs/… image.png

  • 1: 表示XMLHttpRequest 实例已经生成,但是open()方法还没有被调用
  • 2: 表示send()方法还没有被调用,仍然可以使用setRequestHeader(),设定HTTP请求的头信息
  • 3: 表示send()方法已经执行,并且头信息和状态码已经收到
  • 4: 表示正在接收服务器传来的body 部分的数据
  • 5: 表示服务器数据已经完全接收,或者本次接收已经失败了

3.10 API总结

  • XMLHttpRequest():创建 XHR 对象的构造函数
  • status:响应状态码值,如 200、404
  • statusText:响应状态文本,如 ’ok‘、‘not found’
  • readyState:标识请求状态的只读属性 0-1-2-3-4
  • onreadystatechange:绑定 readyState 改变的监听
  • responseType:指定响应数据类型,如果是 ‘json’,得到响应后自动解析响应
  • response:响应体数据,类型取决于 responseType 的指定
  • timeout:指定请求超时时间,默认为 0 代表没有限制
  • ontimeout:绑定超时的监听
  • onerror:绑定请求网络错误的监听
  • open():初始化一个请求,参数为:(method, url[, async])
  • send(data):发送请求
  • abort():中断请求 (发出到返回之间)
  • getResponseHeader(name):获取指定名称的响应头值
  • getAllResponseHeaders():获取所有响应头组成的字符串
  • setRequestHeader(name, value):设置请求头