Ajax学习笔记(一):原生AJAX、HTTP协议、AJAX案例准备工作、发送AJAX请求、AJAX 请求状态

目录

一、原生AJAX

[1.1AJAX 简介](#1.1AJAX 简介)

[1.2 XML 简介](#1.2 XML 简介)

[1.3 AJAX的特点](#1.3 AJAX的特点)

二、HTTP协议

三、AJAX案例准备工作

四、发送AJAX请求

1.发送GET请求

2.发送POST请求

3.JSON响应

IE缓存问题:

[五、AJAX 请求状态](#五、AJAX 请求状态)


一、原生AJAX

1.1AJAX 简介

AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。

通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。

AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式

比如百度搜索框:

搜索abcd,下面出现的提示框就是用到Ajax,提示框中的信息不是自动生成的,而是向服务器发送请求,数据从服务器返回。

注册页面:

当我们输入一个用户名,不可以时,会提示此用户名太受欢迎,请更换一个,也是运用了Ajax。

1.2 XML 简介

XML 可扩展标记语言。XML 被设计用来传输和存储数据。XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签,全都是自定义标签,用来表示一些数据。(现在已经被 JSON 取代了。)

1.3 AJAX的特点

1.3.1 AJAX的优点

  1. 可以无需刷新页面而与服务器端进行通信。

  2. 允许你根据用户事件来更新部分页面内容。

1.3.2 AJAX的缺点

  1. 没有浏览历史,不能回退

  2. 存在跨域问题(同源)

  3. SEO 不友好

二、HTTP协议

HTTP全称为hypertext transport protocol 协议【超文本传输协议】,协议详细规定了浏览器和万维网服务器之间互相通信的规则。

重点是格式与参数:

1.请求报文

行: GET/POST /URL HTTP 协议版本

头: Host:值 cookie:值 Content-type:值 User-Agent:值 等等

空行:

体: 如果是GET请求体为空,如果是POST可以不为空

2.响应报文

行: HTTP协议版本 响应状态码 响应状态字符串

头: Content-type:值 Content-length:值 Content-encoding:值 等等

体: HTML语法内容

<html>

<head>

</head>

<body>

<h1>月薪过万</h1>

</body>

</html>

三、AJAX案例准备工作

1.安装express

只需要在vscode => 终端 => 当前目录中 => 输入npm init --yes。

2.创建一个js文件

在当前目录下新建js文件(不一定非要在express安装的根目录),然后在终端=>当前目录下=>输入 node 文件名 就可以启动服务

报错:Error: listen EADDRINUSE: address already in use :::8000

如果端口被占用,找到前一个服务关闭,在终端CTRL+C端口释放,然后重新再到需要开启服务的终端输入node 文件名。

四、发送AJAX请求

1.发送GET请求

点击按钮div:点击按钮发送AJAX请求给服务器,然后把响应体拿过来放到div中。

这部分看不太懂,只是照着敲了一边,后面再回来补。

javascript 复制代码
<button>点击发送请求</button>
 <div id="result"></div>

<script>
      // 获取button元素
      const btn = document.getElementsByTagName('button')[0]
      const result = document.getElementById('result')
      // 绑定事件
      btn.onclick = function () {
        //1. 创建对象
        const xhr = new XMLHttpRequest()
        //2. 初始化 设置请求方法和 url
        xhr.open('GET', 'http:127.0.0.1:8000/server?a=100&b=200&c=300')
        //3. 发送
        xhr.send()
        //4. 事件绑定 处理服务端返回的结果
        // on    当....时候
        // readystate 是 xhr 对象中的属性 , 表示状态 0 1 2 3 4
        //其中0-未初始化 1-open调用完毕 2-send调用完毕 3-服务端返回了部分结果 4-服
务端返回了所有结果
        //change 改变
        xhr.onreadystatechange = function () {
          // 判断(服务器返回了所有的结果)
          if (xhr.readyState === 4) {
            // 判断响应状态码 200   404   403   401    500
            // 2xx  成功
            if (xhr.status >= 200 && xhr.status < 300) {
              //处理结果  行  头  空行  体
              //响应
              // console.log(xhr.status) //状态码
              // console.log(xhr.statusText) //状态字符串
              // console.log(xhr.getAllResponseHeaders()) //所有响应头
              // console.log(xhr.response) //响应体
              // 设置 result 的文本
              result.innerHTML = xhr.response
            }
          }
        }
      }
    </script>

设置url参数:用?隔开,=赋值,&分隔

例如:http://127.0.0.1:8000/server?a=1\&b=2\&c=3

Server.js 文件:

javascript 复制代码
//1. 引入express
const express = require('express')
//2. 创建应用对象
const app = express()
//3. 创建路由规则
// resquest 是对请求报文的封装
// response 是对响应报文的封装
app.get('/server', (request, response) => {
  // 设置响应头  设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  // 设置响应体
  response.send('HELLO AJAX')
})
//4. 监听端口启动服务
app.listen(8000, () => {
  console.log('服务已经启动,8000 端口监听中...')
})

2.发送POST请求

鼠标经过div发送AJAX请求,然后拿回来响应体放在div中

html 复制代码
 <div id="result"></div>

传参在send中写,任何类型都可以

可以在xhr.setRequestHeader 设置请求头,不懂可以看下注释

javascript 复制代码
<script>
      // 获取元素对象
      const result = document.getElementById('result')
      // 绑定事件
      result.addEventListener('mouseover', function () {
        //1. 创建对象
        const xhr = new XMLHttpRequest()
        //2. 初始化 设置类型与 URL
        xhr.open('POST', 'http://127.0.0.1:8000/server')
        // 设置请求头:固定写法,第一个参数设置请求体内容类型,第二个参数是参数查询字符串的类型
        xhr.setRequestHeader(
          'Content-Type',
          'application/x-www-form-urlencoded'
        )
        //3. 发送  在这里传值 任何类型都可
        xhr.send('a=100&b=200&c=300')
        // xhr.send('a:100&b:200&c:300')
        // xhr.send('123456')
        //4. 事件绑定
        xhr.onreadystatechange = function () {
          // 判断
          if (xhr.readyState === 4) {
            if (xhr.status >= 200 && xhr.status < 300) {
              // 处理服务端返回的结果
              result.innerHTML = xhr.response
            }
          }
        }
      })
    </script>

server.js

javascript 复制代码
//1. 引入express
const express = require('express')
//2. 创建应用对象
const app = express()
//3. 创建路由规则
// resquest 是对请求报文的封装
// response 是对响应报文的封装
app.post('/server', (request, response) => {
  // 设置响应头  设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  // 设置响应体
  response.send('HELLO AJAX POST')
})
//4. 监听端口启动服务
app.listen(8000, () => {
  console.log('服务已经启动,8000 端口监听中...')
})

3.JSON响应

键盘按下任意按下一个按键,就会向服务端发送请求,服务端返回结果,结果在div中呈现

服务端响应体也可以设置为一个数据发送过去,但是不能直接写,要通过JSON.stringify(数据)把数据转换为JSON字符串

javascript 复制代码
app.get('/json-server', (request, response) => {
    //设置响应头
    response.setHeader('Access-Control-Allow-Origin', '*');
    //响应一个数据
    const data = { name: 'atguigu'};
    let str = JSON.stringify(data); //对对象进行字符串转换
    //设置响应体
    response.send(str);
})

(1)手动把JSON字符串转换为js对象

借助JSON.parse(xhr.response)

javascript 复制代码
let data = JSON.parse(xhr.response);
console.log(data);  //js对象:{ name: 'ht' }
result.innerHTML = data.name;

(2)自动把JSON字符串转换为js对象

借助 xhr.responseType = 'json';

javascript 复制代码
xhr.responseType = 'json';
......
console.log(xhr.response); //js对象:{ name: 'ht' }
result.innerHTML = xhr.response.name;

nodemon实现保存自动重启服务

终端运行npm install -g nodemon安装nodemon,这样每次保存就会自动重启服务,比较方便(副作用是所有html都无法保存时自动调整格式),使用时还是在当前目录nodemon+文件名 ,如

nodemon server.js(之前是node server.js)

IE缓存问题:

在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求,剩

余多次请求不会在发送给浏览器而是直接加载缓存中的数据。

解决方式:浏览器的缓存是根据 url 地址来记录的,所以我们只需要修改 url 地址

即可避免缓存问题

xhr.open("get","/testAJAX?t="+Date.now());

javascript 复制代码
app.get('/ie', (request, response) => {
  // 设置响应头  设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  // 设置响应体
  response.send('HELLO IE - 3')
})


 xhr.open('GET', 'http://127.0.0.1:8000/ie?t=' + Date.now()) //获取当前时间戳

2.AJAX请求超时与网络异常处理

服务器写个定时器,3秒后发送响应体

javascript 复制代码
//延时响应
app.get('/delay', (request, response) => {
  // 设置响应头  设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  setTimeout(() => {
    // 设置响应体
    response.send('延时响应')
  }, 3000)
})

然后点击按钮发送请求时,可以设置超时xhr.timeout和超时回调xhr.ontimeout,还有网络异常回

调xhr.onerror

javascript 复制代码
const xhr = new XMLHttpRequest()
        //超时设置 2s 设置
        xhr.timeout = 2000
        //超时回调
        xhr.ontimeout = function () {
          alert('网络异常,请稍后重试!!!')
        }
        //网络异常回调
        xhr.onerror = function () {
          alert('您的网络似乎出现了一些问题')
        }

浏览器可以手动断网offine

3.AJAX手动取消请求

定时器发送响应体

javascript 复制代码
app.get('/cancel', (request, response) => {
  //设置响应头
  response.setHeader('Access-Control-Allow-Origin', '*')
  //设置响应体
  setTimeout(() => {
    response.send('HELLO 我请求被取消了,没法发过去了')
  }, 3000)
})

写两个按钮

html 复制代码
<button>点击发送</button>
    <button>点击取消</button>

取消请求,用xhr.abort()方法,abort中文意思是中止

这里边儿有个作用域的问题,解决方法是把xhr定义在外边给个null,然后赋值xhr实例,再调用方法。(重复赋值不要用const,能用const就用const,不能const就let,反正不能用var)

javascript 复制代码
// 获取元素对象
      const btns = document.querySelectorAll('button')
      let xhr = null
      btns[0].onclick = function () {
        xhr = new XMLHttpRequest()
        xhr.open('GET', 'http://127.0.0.1:8000/cancel')
        xhr.send() // 不用拿响应体,所有后面不写了
      }
      //取消请求 abort
      btns[1].onclick = function () {
        xhr.abort() //先点send再点cancel不会报错,反之报错
        // console.log(xhr)
      }

4.AJAX请求重复发送问题

服务端还是用的前面的定时器,这里重复请求写个逻辑,如果没处在请求中,就创建新的请求;如果已经请求了,就废掉,再重新创建请求。

javascript 复制代码
 // 获取元素对象
      const btns = document.querySelectorAll('button')
      let xhr = null
      // 标识变量
      let isSending = false // 是否正在发送AJAX请求
      btns[0].onclick = function () {
        // 判断标识符变量
        if (isSending) xhr.abort() // 如果正在发生,则取消该请求,创建一个新的请求
        xhr = new XMLHttpRequest()
        // 修改 标识变量的值
        isSending = true
        xhr.open('GET', 'http://127.0.0.1:8000/cancel')
        xhr.send()
        xhr.onreadystatechange = function () {
          if (xhr.readyState === 4) {
            // 修改标识变量 有可能请求失败,所以这里不用再做判断,只要拿到结果,就算请求完成
            isSending = false // 拿到服务器的全部结果后,置为false
          }
        }
      }

五、AJAX 请求状态

xhr.readyState 可以用来查看请求当前的状态

XMLHttpRequest.readyState - Web API 接口参考 | MDN

0: 表示 XMLHttpRequest 实例已经生成,但是 open()方法还没有被调用。

1: 表示 send()方法还没有被调用,仍然可以使用 setRequestHeader(),设定 HTTP请求的头信息。

2: 表示 send()方法已经执行,并且头信息和状态码已经收到。

3: 表示正在接收服务器传来的 body 部分的数据。

4: 表示服务器数据已经完全接收,或者本次接收已经失败了

相关推荐
Chef_Chen4 分钟前
从0开始学习机器学习--Day33--机器学习阶段总结
人工智能·学习·机器学习
hopetomorrow44 分钟前
学习路之压力测试--jmeter安装教程
学习·jmeter·压力测试
hopetomorrow1 小时前
学习路之PHP--使用GROUP BY 发生错误 SELECT list is not in GROUP BY clause .......... 解决
开发语言·学习·php
/**书香门第*/1 小时前
Cocos creator 3.8 支持的动画 7
学习·游戏·游戏引擎·游戏程序·cocos2d
美式小田2 小时前
单片机学习笔记 9. 8×8LED点阵屏
笔记·单片机·嵌入式硬件·学习
猫爪笔记2 小时前
前端:HTML (学习笔记)【2】
前端·笔记·学习·html
_不会dp不改名_2 小时前
HCIA笔记3--TCP-UDP-交换机工作原理
笔记·tcp/ip·udp
-一杯为品-2 小时前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
风尚云网3 小时前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
熙曦Sakura4 小时前
完全竞争市场
笔记