AJAX笔记

128 阅读4分钟

AJAX笔记

1.express框架

1.1 安装nodejs【后续补充】

1.2 安装express依赖

npm i express

1.3 服务端设置

1.3.1 服务器端设置步骤详解

  • [ 引入express] const express = require('express')
  • [ 创建应用对象] const app = express()
  • [ 创建路由规则] app.get/post/all('/', (request, response) => { // 设置响应 response.send('HELLO,EXPRESS')})
  • [ 监听端口]
    app.listen(8080, () => { console.log("服务已启动,8080端口监听中······") })

1.3.2 服务器端设置代码示例

// 1.引入express
const express = require('express')

// 2.创建应用对象
const app = express()

// 3.创建路由规则
app.get('/', (request, response) => {
  // 设置响应
  response.send('HELLO,EXPRESS')
})

app.post('/server', (request, response) => {
  // 设置响应头  允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  // 设置响应体
  response.send('HELLO,EXPRESS POST')
})

// 若是要完成请求头自定义  all--刻意接收任何类型的请求
app.all('/json-server', (request, response) => {
  // 设置响应头  允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  // 表示所有类型的头信息都可以接收
  response.setHeader('Access-Control-Allow-Headers', '*')

  // 响应一个数据
  const data = {
    name: 'zhangsan',
    age: 14
  }
  // 对对象进行字符串转化
  let str = JSON.stringify(data)

  // 设置响应体
  response.send(str)
})

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

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


// 4.监听端口
app.listen(8080, () => {
  console.log("服务已启动,8080端口监听中······")
})

2.原生AJAX请求与响应

2.1 发起请求步骤详解

  • [ 创建对象] const xhr = new XMLHttpRequest()

  • [ 设置响应体数据的类型] xhr.responseType = 'json'

  • [ 初始化] xhr.open('请求方式:GET/POST','请求地址:http://localhost:8000/···')

  • [ 设置请求头(Content-Type设置请求体内容的类型)] xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

  • [ 发送] xhr.send('可以放要传递的数据,也可以不放')

  • [ 事件绑定(处理服务端的结果)] xhr.onreadystatechange = function(){}

  • [ 事件绑定的函数体内容]

if (xhr.readyState === 4) {
    if (xhr.status >= 200 && xhr.status < 300) {
       xhr.response  // 响应结果
    }
}

2.2 GET请求代码示例

<button>点击发送请求</button>
<div id="result" style="width: 200px;height: 100px;border: 1px solid red;"></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://localhost:8000/server?a=100&b=200&c=300')  // 请求时携带参数
        // 3. 发送
        xhr.send()
        // 4.事件绑定 处理服务端返回的结果
        // on   when 当···的时候
        // 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>

2.3 POST请求代码示例

<div id="result" style="width: 200px;height: 100px;border: 1px solid red;"></div>

<script>
    // 获取元素对象
    const result = document.getElementById('result')
    // 绑定事件
    result.addEventListener('mouseover', function () {
      // 1.创建对象
      const xhr = new XMLHttpRequest()
      // 2.初始化 设置类型与URL
      xhr.open('POST', 'http://localhost:8000/server')
      // 设置请求头  Content-Type设置请求体内容的类型 
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
      // 3.发送
      xhr.send('a=100&b=200&c=300')
      // 4.事件绑定
      xhr.onreadystatechange = function () {
        // 判断
        if (xhr.readyState === 4) {
          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>

2.4 ajax请求响应

<div id="result" style="width: 200px;height: 100px;border: 1px solid red;"></div>

<script>
    // 获取元素对象
    const result = document.getElementById('result')
    // 绑定键盘按下事件
    window.onkeydown = function () {
      // 发送请求
      const xhr = new XMLHttpRequest()
      // 设置响应体数据的类型
      xhr.responseType = 'json'
      // 初始化
      xhr.open('GET', 'http://localhost:8000/json-server')
      // 发送
      xhr.send()
      // 事件绑定
      xhr.onreadystatechange = function () {
        // 判断
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            // 手动对数据进行转化
            // let data = JSON.parse(xhr.response)
            // console.log(data)
            // result.innerHTML = data.name
            // 自动转化数据
            console.log(xhr.response)
            result.innerHTML = xhr.response.name
          }
        }
      }
    }
</script>

2.5 IE缓存问题

<button>点击发送请求</button>
<div id="result" style="width: 200px;height: 100px;border: 1px solid red;"></div>

<script>
    const btn = document.getElementsByTagName('button')[0]
    const result = document.getElementById('result')

    btn.addEventListener('click', function () {
      const xhr = new XMLHttpRequest()
      xhr.open('GET', 'http://localhost:8000/ie?t=' + Date.now())  // 获取时间戳,保证每一次都是新的请求
      xhr.send()
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            result.innerHTML = xhr.response
          }
        }
      }
    })
</script>

2.6 请求超时与网络异常处理

<button>点击发送请求</button>
<div id="result" style="width: 200px;height: 100px;border: 1px solid red;"></div>

<script>
    const btn = document.getElementsByTagName('button')[0]
    const result = document.getElementById('result')

    btn.addEventListener('click', function () {
      const xhr = new XMLHttpRequest()

      // 超时设置 2s
      xhr.timeout = 2000

      // 超时回调
      xhr.ontimeout = function () {
        alert('网络超时,请稍后重试!!!')
      }

      // 网络异常回调
      xhr.onerror = function () {
        alert('你的网络似乎出现了问题!!!')
      }

      xhr.open('GET', 'http://localhost:8000/settimeout')  // 获取时间戳,保证每一次都是新的请求
      xhr.send()
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            result.innerHTML = xhr.response
          }
        }
      }
    })
</script>

2.7 取消请求 【abort()方法】

<button>点击发送</button>
<button>点击取消</button>

<script>
    // 获取元素对象
    const btns = document.getElementsByTagName('button')
    let x = null
    btns[0].onclick = function () {
      x = new XMLHttpRequest()
      x.open('GET', 'http://localhost:8000/settimeout')
      x.send()
    }

    // abort()方法 手动取消请求
    btns[1].onclick = function () {
      x.abort()
    }
</script>

2.8 重复请求问题

<button>点击发送</button>

<script>
    // 获取元素对象
    const btns = document.getElementsByTagName('button')
    let x = null
    // 标识变量
    let isSending = false //是否正在发送ajax请求
    btns[0].onclick = function () {
      // 判断标识变量
      if (isSending) x.abort()  // 如果正在发送,则取消该请求,创建一个新的请求
      x = new XMLHttpRequest()
      // 修改 标识变量的值
      isSending = true
      x.open('GET', 'http://localhost:8000/settimeout')
      x.send()
      x.onreadystatechange = function () {
        if (x.readyState === 4) {
          isSending = false
        }
      }
    }
</script>

3. jQuery-AJAX

3.1 引入jQuery

www.bootcdn.cn/ 里获取jQuery链接

image.png

image.png

3.2 请求与响应

$.get/post('url',url参数,回调函数:function(data){},'数据格式:json')

$ajax({
    // url
    url: 'url地址',
    // 参数
    data: {},
    // 请求类型
    type: 'GET/POST',
    // 响应体结果格式
    dataType: 'json',
    // 成功回调
    success:function(data){
        console.log(data)
    },
    // 超时时间
    timeout: 2000,
    // 失败回调
    error:function(){
        alert('出错啦!!!')
    },
    // 头信息
    headers: {}
})

3.3 代码示例

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.js"></script>

<button>GET请求</button>
<button>POST请求</button>
<button>通用型方法ajax</button>

<script>
    // GET请求
    $('button').eq(0).click(function () {
      $.get('http://localhost:8000/jquery', { a: 100, b: 200 }, function (data) {
        console.log(data)
      }, 'json')
    })
    
    // POST请求
    $('button').eq(1).click(function () {
      $.post('http://localhost:8000/jquery', { a: 100, b: 200 }, function (data) {
        console.log(data)
      })
    })
    
    // 通用型方法ajax
    $('button').eq(2).click(function () {
      $.ajax({
        // url
        url: 'http://localhost:8000/jquery',
        // 参数
        data: { a: 100, b: 100 },
        // 请求类型
        type: 'GET',
        // 响应体结果格式
        dataType: 'json',
        // 成功回调
        success: function (data) {
          console.log(data)
        },
        // 超时时间
        timeout: 2000,
        // 失败的回调
        error: function () {
          alert('出错啦!!!')
        },
        // 头信息
        headers: {
          c: 300,
          d: 400
        }
      })
    })
</script>

4.axios-AJAX

4.1 引入 axios

参考 3.1 jQuery引入

<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.2/axios.min.js"></script>

4.2 请求与响应

axios.get/post('url地址',{
    // url参数
    params: {},
    // 请求头信息
    headers: {},
}).then(value => {
    console.log(value)
})

axios({
    // url地址
    url: '',
    // url参数
    params: {},
    // 请求方法
    method: 'GET/POST',
    // 头信息
    headers: {},
    // 请求体参数
    data: {},
}).then(response => {})

4.3 代码示例

<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.2/axios.min.js"></script>

<button>GET</button>
<button>POST</button>
<button>AJAX</button>

<script>
    const btns = document.querySelectorAll('button')

    // 配置 baseURL
    axios.defaults.baseURL = 'http://localhost:8000'

    btns[0].onclick = function () {
      // GET请求
      axios.get('/axios-server', {
        // url 参数
        params: {
          id: 100,
          vip: 7
        },
        // 请求头信息
        headers: {
          name: 'lisi',
          age: 20
        }
      }).then(value => {
        console.log(value)
      })
    }

    btns[1].onclick = function () {
      axios.post('/axios-server',
        // 请求体
        {
          username: 'admin',
          password: '123456'
        },
        {
          // url
          params: {
            id: 200,
            vip: 9
          },
          // 请求头参数
          headers: {
            height: 180,
            weight: 140
          },
        })
    }

    btns[2].onclick = function () {
      axios({
        // url
        url: '/axios-server',
        // 请求方法
        method: 'POST',
        // url参数
        params: {
          vip: 10,
          level: 30,
        },
        // 头信息
        headers: {
          a: 100,
          b: 200,
        },
        // 请求体参数
        data: {
          username: 'admin',
          password: '123456'
        }
      }).then(response => {
        console.log(response)
        console.log('响应状态码', response.status)
        console.log('响应状态字符串', response.statusText)
        console.log('响应头信息', response.headers)
        console.log('响应体', response.data)
      })
    }
  </script>

5. fetch-AJAX

5.1 请求与响应

fetch('url地址',{
    // 请求方法
    method: 'GET/POST',
    // 请求头
    headers: {},
    // 请求体
    body: ''
}).then(response => {
    return response.json()
}).then(response => {
    console.log(response)
})

5.2 代码示例

<button>AJAX请求</button>

<script>
    const btn = document.querySelector('button')

    btn.onclick = function () {
      fetch('http://localhost:8000/fetch-server?vip=50&level=1000', {
        // 请求方法
        method: 'POST',
        //请求头
        headers: {
          name: 'less'
        },
        // 请求体
        body: 'username=admin&password=123456'
      }).then(response => {
        // return response.text()
        return response.json()
      }).then(response => {
        console.log(response)
      })
</script>

6. 跨域问题

6.1 同源策略

最早由 Netscape 公司提出,是浏览器的一种安全策略

同源:协议、域名、端口号 必须完全相同

违背同源策略就是跨域

6.2 解决跨域--JSONP

  • [ JSONP] :一个官方的跨域解决方案,只支持 get 请求

  • [ 原理]:在网页上有一些标签天生具有跨域能力,比如:img link iframe script ,JSONP 就是利用 script 标签的跨域能力来发送请求的

  • [ 原生JSONP实践] 客户端

用户名:<input type="text" id="username">
<p></p>

<script>
    // 获取 input 元素
    const input = document.querySelector('input')
    // 获取p标签元素
    const p = document.querySelector('p')

    // 声明 handle 函数
    function handle (data) {
      input.style.border = '1px solid red'
      // 修改p标签的提示文本
      p.innerHTML = data.msg
    }

    // 绑定事件
    input.onblur = function () {
      //获取用户输入值
      let username = this.value
      // 向服务器端发送请求  检测用户名是否存在
      // 1. 创建 script 标签
      const script = document.createElement('script')
      // 2.设置标签的src属性
      script.src = 'http://localhost:8000/check-username'
      // 3.将 script 插入到文档中
      document.body.appendChild(script)
    }
</script>

服务端

// 1.引入express
const express = require('express')

// 2.创建应用对象
const app = express()

// 3.创建路由规则
// 检测用户名是否存在
app.all('/check-username', (request, response) => {
  const data = {
    exist: 1,
    msg: "用户名已存在"
  }
  // 将数据转化为字符串
  let str = JSON.stringify(data)
  // 返回结果
  response.end(`handle(${str})`)
})

// 4.监听端口
app.listen(8000, () => {
  console.log("服务已启动,8000端口监听中······")
})

// 安装nodemon,只要server文件内容更改,就会自动重启端口
// 安装命令 npm install -g nodemon
  • [ jQuery-JSONP实践] 客户端
 <style>
    #result {
      width: 200px;
      height: 100px;
      border: 1px solid red;
    }
  </style>
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.js"></script>

 <button>点击发送请求</button>
 <div id="result"></div>
 
 <script>
    $('button').eq(0).click(function () {
      $.getJSON('http://localhost:8000/jquery-jsonp-server?callback=?', function (data) {
        $('#result').html(`名称:${data.name}<br>城市:${data.city}`)
      })
    })
  </script>

服务端

// 1.引入express
const express = require('express')

// 2.创建应用对象
const app = express()

// 3.创建路由规则
// jquery-jsonp 服务
app.all('/jquery-jsonp-server', (request, response) => {
  const data = {
    name: '张三',
    city: "湖南长沙"
  }
  // 将数据转化为字符串
  let str = JSON.stringify(data)

  // 接收 callback 参数
  let cb = request.query.callback

  // 返回结果
  response.end(`${cb}(${str})`)
})

// 4.监听端口
app.listen(8000, () => {
  console.log("服务已启动,8000端口监听中······")
})

6.3 解决跨域--CORS

  • [ cors]: 通过服务端的请求头来实现跨域response.setHeader('Access-Control-Allow-Origin', '*)

  • [ 代码示例] 客户端

<style>
    #result {
      width: 200px;
      height: 100px;
      border: 1px solid red;
    }
</style>

<button>点击发送请求</button>
<div id="result"></div>
 
<script>
    const btn = document.querySelector('button')

    btn.onclick = function () {
      // 1.创建对象
      const xhr = new XMLHttpRequest()
      // 2.初始化设置
      xhr.open("GET", "http://localhost:8000/cors-server")
      // 3.发送
      xhr.send()
      // 4.绑定事件
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            // 输出响应体
            console.log(xhr.response)
          }
        }
      }
    }
</script>

服务端

/ 1.引入express
const express = require('express')

// 2.创建应用对象
const app = express()

// 3.创建路由规则
// cors 服务
app.all('/cors-server', (request, response) => {
  // 设置响应头
  response.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')
  response.send('hello CORS')
})


// 4.监听端口
app.listen(8000, () => {
  console.log("服务已启动,8000端口监听中······")
})