Ajax编程基础

Ajax基础

1. 传统网站中存在的问题
  • 网速慢的情况下, 页面加载时间长, 用户只能等待
  • 表单提交后, 如果一项内容不合格, 需要重新填写所有表单内容
  • 页面跳转, 重新加载页面, 造成资源浪费, 增加用户等待时间
2. Ajax概述

它是浏览器提供的一套方法, 可以实现页面无刷新更新数据, 提高用户浏览网站应用体验

3. Ajax的应用场景
  1. 页面上拉加载更多数据
  2. 列表数据无刷新分页
  3. 表单项离开焦点数据验证
  4. 搜索框提示文字下拉列表
4. Ajax 的运行环境

Ajax技术需要运行在网站环境中才能生效, 可以使用Node创建服务器作为网站服务器。

Ajax 运行原理及实现

1. Ajax 运行原理

Ajax相当于浏览器发送请求与接收响应的代理人, 以实现在不影响用户浏览页面的情况下, 局部更新页面数据, 从而提高用户体验。
在这里插入图片描述

2. Ajax 的实现步骤
  • 创建 Ajax 对象
var xhr = new XMLHttpRequest();
  • 告诉Ajax请求地址以及请求方式
xhr.open('get', 'http://www.example.com')
  • 发送请求
xhr.send()
  • 获取服务器端与客户端的响应数据
xhr.onload = function () {
	console.log(xhr.responseText)
}

服务端代码

const express = require('express')

const path = require('path')

const app = express()

app.use(express.static(path.join(__dirname, 'public')))

app.get('/first', (req, res) => {
  res.send('hello ajax')
})

app.listen(3000, () => console.log('服务器启动成功'))

ajax代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // 1. 创建ajax对象
    const xhr = new XMLHttpRequest()
    // 2. 告诉ajax对象要向哪发送请求, 以什么方式发送请求
    // 1) 请求方式 2)请求地址
    xhr.open('get', 'http://localhost:3000/first')
    // 3. 发送请求
    xhr.send()
    // 4. 获取服务器端响应到客户端的数据
    xhr.onload = function () {
      console.log(xhr.responseText)
    }
  </script>
</body>
</html>

运行结果
在这里插入图片描述

3. 服务器端响应的数据格式

在真实的项目中, 服务器端大多数情况下会以JSON对象作为响应数据的格式。当客户端拿到响应数据时,要将JSON数据和HTML字符串进行拼接,然后将拼接的结果展示在页面中。

  • ajax代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    const xhr = new XMLHttpRequest()
    xhr.open('get', 'http://localhost:3000/responseData')
    xhr.send()
    xhr.onload = function () {
      console.log(xhr.responseText)
      console.log(typeof xhr.responseText)
    }
  </script>
</body>
</html>
  • 服务端代码
const express = require('express')

const path = require('path')

const app = express()

app.use(express.static(path.join(__dirname, 'public')))

app.get('/first', (req, res) => {
  res.send('hello ajax')
})

app.get('/responseData', (req, res) => {
  res.send({"name": "zhangsan"})
})

app.listen(3000, () => console.log('服务器启动成功'))

  • 运行结果
    在这里插入图片描述

在 http 请求与响应的过程中, 无论是请求参数还是响应内容, 如果是对象对象类型, 最终都会被转换为对象字符串进行传输。
JSON.psrse() // 将json字符串转换为json对象

  • ajax代码
const xhr = new XMLHttpRequest()
    xhr.open('get', 'http://localhost:3000/responseData')
    xhr.send()
    xhr.onload = function () {
    // 将JSON字符串转换为JSON对象
      let responseText = JSON.parse(xhr.responseText)
      console.log(responseText)
      var str = '<h2>' + responseText.name + '</h2>'
      document.body.innerHTML = str
    }
  • 服务端代码和上面的一样
  • 运行结果
    在这里插入图片描述
4. 请求参数传递
4.1. get请求参数
  • ajax代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <p>
    <input type="text" id="username">
  </p>
  <p>
    <input type="text" id="age">
  </p>
  <p>
    <input type="button" value="提交" id="btn">
  </p>
  <script>
    var btn = document.getElementById('btn')
    var username = document.getElementById('username')
    var age = document.getElementById('age')

    btn.onclick = function () {
      // 创建ajax对象
      const xhr = new XMLHttpRequest()
      // 获取用户在文本框中的数据值
      var nameValue = username.value
      var ageValue = age.value
      // 拼接请求参数
      var params = 'username=' + nameValue + '&age=' + ageValue

      // 配置ajax对象
      xhr.open('get', 'http://localhost:3000/get?' + params)
      // 发送请求
      xhr.send()
      // 获取服务器端的响应数据
      xhr.onload = function () {
        console.log(xhr.responseText)
      }
    }
  </script>
</body>
</html>
  • js代码
const express = require('express')

const path = require('path')

const app = express()

app.use(express.static(path.join(__dirname, 'public')))

app.get('/first', (req, res) => {
  res.send('hello ajax')
})

app.get('/responseData', (req, res) => {
  res.send({"name": "zhangsan"})
})

app.get('/get', (req, res) => {
  res.send(req.query)
})

app.listen(3000, () => console.log('服务器启动成功'))

4.2. post请求
  • ajax代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <p>
    <input type="text" id="username">
  </p>
  <p>
    <input type="text" id="age">
  </p>
  <p>
    <input type="button" value="提交" id="btn">
  </p>
  <script>
    var btn = document.getElementById('btn')
    var username = document.getElementById('username')
    var age = document.getElementById('age')

    btn.onclick = function () {
      // 创建ajax对象
      const xhr = new XMLHttpRequest()
      // 获取用户在文本框中的数据值
      var nameValue = username.value
      var ageValue = age.value
      // 拼接请求参数
      var params = 'username=' + nameValue + '&age=' + ageValue

      // 配置ajax对象
      xhr.open('post', 'http://localhost:3000/post')
      // 设置请求参数格式的类型, post请求必须设置
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
      // 发送请求
      xhr.send(params)
      // 获取服务器端的响应数据
      xhr.onload = function () {
        console.log(xhr.responseText)
      }
    }
  </script>
</body>
</html>
  • 服务端代码
const express = require('express')
const bodyParser = require('body-parser')

const path = require('path')

const app = express()

app.use(bodyParser.urlencoded({ extended: false }))

app.use(express.static(path.join(__dirname, 'public')))

app.get('/first', (req, res) => {
  res.send('hello ajax')
})

app.get('/responseData', (req, res) => {
  res.send({"name": "zhangsan"})
})

app.get('/get', (req, res) => {
  res.send(req.query)
})

app.post('/post', (req, res) => {
  res.send(req.body)
})

app.listen(3000, () => console.log('服务器启动成功'))

  • 运行结果
    在这里插入图片描述
4.3. 请求报文
  • 在HTTP请求和响应过程中传递的数据块就叫报文, 包括要传递的数据和一些附加信息, 这些数据和信息要遵守规定好的格式
    在这里插入图片描述
5.请求参数的格式
  1. application/x-www-form-urlencoded

name=zhangsan&age=20

  1. application/json

{ name: ‘zhangsan’, age: ‘20’ }

  1. 在请求头中指定 Content-Type 属性的值是 application/json, 告诉服务器端挡墙请求参数的格式是json

JSON.stringify() // 将json对象转换为json字符串

  • ajax代码
// 创建ajax对象
    const xhr = new XMLHttpRequest()
    // 配置ajax对象
    xhr.open('post', 'http://localhost:3000/json')
    xhr.setRequestHeader('Content-Type', 'application/json')
    // 发送请求
    xhr.send(JSON.stringify({name: 'lisi', age: 50}))
    // 获取服务器端的响应数据
    xhr.onload = function () {
      console.log(xhr.responseText)
    }
  • 服务端代码
const express = require('express')
const bodyParser = require('body-parser')

const path = require('path')

const app = express()

app.use(bodyParser.json())

app.use(express.static(path.join(__dirname, 'public')))

app.post('/json', (req, res) => {
  res.send(req.body)
})

app.listen(3000, () => console.log('服务器启动成功'))

注意: get请求是不能提交json对象数据格式的, 传统网站的表单提交验配师不支持json对象数据格式的

6. 获取服务器端的响应
6.1 Ajax状态码
  • 在创建ajax对象, 配置ajax对象, 发送请求, 以及接受完服务器端响应数据, 这个过程中的每一个步骤都会对应一个数值, 这个数值就是ajax状态码

    0: 请求未初始化(还没有调用open())
    1: 请求已经建立, 但是还没有发送(还没有调用send())
    2: 请求已经发送
    3: 请求正在处理中, 通常响应中已经有部分数据可以用了
    4: 响应已经完成, 可以获取并使用服务器的响应了
    xhr.readyState // 获取ajax状态码

  • onreadystatechange 事件

    当ajax状态码发生变化时将自动触发该事件。
    在事件处理函数中可以获取 Ajax状态码并对其进行判断, 当状态码为 4 时就可以通过 xhr.responseText 获取服务器端响应的数据了

  • ajax代码

var xhr = new XMLHttpRequest()
    // 0 已经创建了ajax对象 但是还没有对ajax对象进行配置
    console.log(xhr.readyState)
    xhr.open('get', 'http://localhost:3000/readystate')
    // 1 已经对ajax对象进行配置, 但是会还没有发送请求
    console.log(xhr.readyState)    
    // 当ajax状态码发生变化的时候触发
    xhr.onreadystatechange = function () {
      // 2 请求已经发送了
      // 3 已经接收到服务器端的部分数据了
      // 4 服务器端的响应数据已经接受完成
      console.log(xhr.readyState)
      // 对ajax状态码进行判断 如果状态码的值为 4 就代表数据已经接受完成了
      if (xhr.readyState === 4) {
        console.log(xhr.responseText)
      }
    }
    xhr.send()
  • 服务器端代码
const express = require('express')
const bodyParser = require('body-parser')
const path = require('path')

const app = express()

app.use(bodyParser.json())

app.use(express.static(path.join(__dirname, 'public')))

app.get('/readystate', (req, res) => {
  res.send('ok')
})

app.listen(3000, () => console.log('服务器启动成功'))

6.2 两种获取服务器端响应方式的区别

在这里插入图片描述

7. Ajax 错误处理

  1. 网络通畅, 服务器端能接收到请求, 服务器端返回的结果不是预期结果

    可以判断服务器端返回的状态码, 分别进行处理, xhr.status获取http状态码

  • ajax代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <button id="btn">发送Ajax请求</button>
  <script>
    var btn = document.getElementById('btn')

    btn.onclick = function () {
      var xhr = new XMLHttpRequest()
      xhr.open('get', 'http://localhost:3000/error')
      xhr.send()
      xhr.onload = function () {
        // xhr.status 获取http状态码
        console.log(xhr.responseText)
        if (xhr.status === 400) {
          alert('请求出错')
        }
      }
    }
  </script>
</body>
</html>
  • 服务器端代码
const express = require('express')
const bodyParser = require('body-parser')
const path = require('path')

const app = express()

app.use(bodyParser.json())

app.use(express.static(path.join(__dirname, 'public')))

app.post('/post', (req, res) => {
  res.send(req.body)


app.get('/error', (req, res) => {
  res.status(400).send('not ok')
})

app.listen(3000, () => console.log('服务器启动成功'))

  1. 网络通畅, 服务器端没有接受到请求, 返回 404 状态码

    检查请求地址是否错误

  2. 网络畅通, 服务器端能接受到请求, 服务器端返回 500 状态码

    服务器端错误

  3. 网络中断, 请求无法发送到服务器端

    会触发xhr对象下面的error事件, 在onerror事件处理函数中对错误进行处理

<button id="btn">发送Ajax请求</button>
  <script>
    var btn = document.getElementById('btn')

    btn.onclick = function () {
      var xhr = new XMLHttpRequest()
      xhr.open('get', 'http://localhost:3000/error')
      xhr.send()
      xhr.onload = function () {
        // xhr.status 获取http状态码
        console.log(xhr.responseText)
        if (xhr.status === 400) {
          alert('请求出错')
        }
      }
      // 当网络中断时会触发onerror事件
      xhr.onerror = function () {
        alert('网络中断, 无法发送ajax请求')
      }
    }
  </script>

8. 低版本 IE 浏览器的缓存问题

问题: 在低版本的IE浏览器中, Ajax请求有严重的缓存问题, 即在请求地址不发生变化的情况下, 只有第一次请求会真正发送到服务器端, 后续的请求都会从浏览器的缓存中获取结果, 即使服务器端的数据更新了, 客户端依然拿到的是缓存中的旧数据。

  • ajax 代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <button id="btn">发送Ajax请求</button>
  <script>
    var btn = document.getElementById('btn')

    btn.onclick = function () {
      var xhr = new XMLHttpRequest()
      xhr.open('get', 'http://localhost:3000/cache')
      xhr.send()
      xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
          alert(xhr.responseText)
        }
      }
      // 当网络中断时会触发onerror事件
      xhr.onerror = function () {
        alert('网络中断, 无法发送ajax请求')
      }
    }
  </script>
</body>
</html>
  • 服务端代码
const express = require('express')
const bodyParser = require('body-parser')
const path = require('path')
const fs = require('fs')

const app = express()

app.use(bodyParser.json())

app.use(express.static(path.join(__dirname, 'public')))

app.get('/cache', (req, res) => {
  fs.readFile('./test.txt', (err, result) => {
    res.send(result)
  })
})

app.listen(3000, () => console.log('服务器启动成功'))

  • test.txt文件

hello

运行结果(这里用的是IE 8)
在这里插入图片描述

  • 更改test.txt文件里面的内容为 hello 123
    到浏览器中运行, 结果还是和上面的一样

解决方案
在请求地址的后面加请求参数, 保证每一次请求中的请求参数的值不同

xhr.open('get', 'http://localhost:3000/cache?t=' + Math.random())

运行结果(浏览器是IE 8)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值