3小时Ajax入门到精通

学习笔记
视频相关资料

原生ajax

express框架的基本使用

npm init --yes做一个初始化
npm i express 安装

// 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端口使用中')
})

在终端中 node express的基本使用.js


ajax案例准备

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #result {
      margin-top: 20px;
      width: 300px;
      height: 100px;
      border: 2px solid #5a1216;
    }
  </style>
</head>
<body>
  <button>点击发送请求</button>
  <div id="result"></div>
</body>
</html>
// 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 EXPRESS')
})

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

ajax请求的基本操作

<body>
  <button>点击发送请求</button>
  <div id="result"></div>
  <script>
    const btn = document.getElementsByTagName('button')[0]
    const res = document.querySelector('#result')
    btn.onclick = function() {
      // 1. 创建对象
      const xhr = new XMLHttpRequest();
      // 2. 初始化 设置请求方法和url
      xhr.open('GET', 'http://127.0.0.1:8000/server')
      // 3. 发送
      xhr.send()

      // 4. 事件绑定 处理服务端返回的结果
      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.getAllResponseHeader) // 所有响应头
            // console.log(xhr.response) //响应体
            res.innerHTML = xhr.response

          }
        }
      }
    }
  </script>
</body>

ajax设置请求参数

 xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300')

ajax发送post请求

app.post('/server', (request, response) => {
  // 设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  // 设置响应体
  response.send('HELLO EXPRESS Post')
})
post设置请求体
xhr.send('a=100&b=200&c=300')
xhr.send('a:100&b:200&c:300')

设置请求头

// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.setRequestHeader('name', 'studyAjax')
app.all('/server', (request, response) => {
  // 设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  response.setHeader('Access-Control-Allow-Headers', '*')
  // 设置响应体
  response.send('HELLO EXPRESS Post')
})

服务端响应JSON数据

接收数据时 可以手动转化数据 也可以自动转换

在这里插入图片描述

nodemon

npm install -g nodemon

这个时候要启动js文件就要使用命令nodemon server.js

ajax中的ie缓存问题

xhr.open('GET', 'http://127.0.0.1:8000/server?t='+Date.now())

请求超时与网络异常

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

    // 超时设置
    xhr.timeout = 2000
    xhr.ontimeout = function() {
        alert('网络请求超时')
    }

    xhr.onerror = function() {
        alert('网络异常')
    }

    xhr.open('GET', 'http://127.0.0.1:8000/delay')
    xhr.send()
    xhr.onreadystatechange = function() {
        if(xhr.readyState === 4){
            if(xhr.status >= 200 && xhr.status < 300) {
                res.innerHTML = xhr.response
            }
        }
    }
})
app.get('/delay', (request, response) => {
  // 设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  // 设置响应体
  setTimeout(()=> {
    response.send('延时响应')
  }, 3000)
})

ajax取消请求

const btns = document.querySelectorAll('button')
let x
btns[0].onclick = function() {
    x = new XMLHttpRequest()
    x.open('GET', 'http://localhost:8000/delay')
    x.send()
}
//abort()取消请求
btns[1].onclick = function() {
    x.abort()
}

ajax请求重复发送问题

const btns = document.querySelectorAll('button')
let x
// 标识变量
let isSending = false  // 是否正在发送ajax请求
btns[0].onclick = function() {
    // 如果正在发送,则取消该请求 创建一个新的请求
    if(isSending) x.abort() 
    isSending = true
    x = new XMLHttpRequest()
    x.open('GET', 'http://localhost:8000/delay')
    x.send()
    x.onreadystatechange = function() {
        if(x.readyState === 4) {
            isSending = false
        }
    }
}

btns[1].onclick = function() {
    x.abort()
}

jQuery中的ajax

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
</head>
<body>
  <div class="container">
    <h2 class="page-header">jQuery发送ajax请求</h2>
    <button class="btn btn-primary">GET</button>
    <button class="btn btn-danger">POST</button>
    <button class="btn btn-info">通用方法ajax</button>
  </div>

  <script>
    $('button').eq(0).click(function() {
      $.get('http://127.0.0.1:8000/jquery-server', {a:100,b:200}, function(data) {
        console.log(data)
      }, 'json')
    })

    $('button').eq(1).click(function() {
      $.post('http://127.0.0.1:8000/jquery-server', {a:100,b:200}, function(data) {
        console.log(data)
      }, 'json')
    })
  </script>
</body>
</html>

通用方法发送ajax

$('button').eq(2).click(function() {
    $.ajax({
        // url
        url: 'http://127.0.0.1:8000/jquery-server',
        // 参数
        data: {a: 100, b: 200},
        // 请求类型
        type: 'GET',
        // 响应体结果
        dataType: 'json',
        // 成功的回调
        success: function(data) {
            console.log(data)
        },
        // 超出时间
        timeout: 2000,
        // 失败的回调
        error: function() {
            console.log('出错了')
        },
        // 头信息
        headers: {
          c: 300,
          d: 400
        }
    })
})

axios发送ajax请求

npm i axios 只安装然后直接使用报错

axios发送ajax请求.html:19 Uncaught ReferenceError: axios is not defined

搜到了在vue中使用出错的解决方法 这个直接使用未解决 改为下面的那种方法使用

或者去bootcdn 搜索axios引入script标签

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.js"></script>
</head>
<body>
  <button>get</button>
  <button>post</button>
  <button>unknown</button>
  <script>
    const btns = document.querySelectorAll('button')
    // 配置baseURL
    axios.defaults.baseURL = 'http://localhost:8000'
    btns[0].onclick = function() {
      axios.get('/axios-server', {
        // url参数
        params: {
          id: 100,
          vip: 7
        },
        // 请求头信息
        headers: {
          name: 'study',
          time: 'lasting'
        }
      }).them(value => {
          console.log(value)
      })
    }

    btns[1].onclick = function() {
      axios.post('/axios-server', {
        username: 'keep',
        password: 'study'
      },{
        // url参数
        params: {
          id: 100,
          vip: 7
        },
        // 请求头信息
        headers: {
          name: 'study',
          time: 'lasting'
        }
      })
    }
  </script>
</body>
</html>
btns[2].onclick = function() {
    axios({
        method: 'POST',
        url: '/axios-server',
        // url参数
        params: {
            a: 100,
            b: 200
        },
        // 请求头信息
        headers: {
            c: 'heders',
            d: 'info'
        },
        // 请求体
        data: {
            username: 'admin',
            password: 'admin'
        }
    }).then(response => {
        console.log(response)
        console.log(response.status)
        console.log(response.statusText)
        console.log(response.data)
    })
}

使用fetch()

const btn = document.querySelector('button')

    btn.onclick = function() {
      fetch('http://127.0.0.1:8000/fetch-server?vip="李准基"', {
        // 请求方式
        method: 'POST',
        // 请求头
        headers: {
          name: 'study'
        },
        // 请求体
        body: 'username=admin&password=admin'
      }).then(resopnse => {
        return response.text()
      }).then(response => {
        console.log(response)
      })
    }

同源策略

同源策略是浏览器的一种安全策略

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

违背同源策略就是跨域

ajax发送请求默认使用同源策略

同源策略案例

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>学习AJAX</h1>
  <button>点击获取用户数据</button>
  <script>
    const btn = document.querySelector('button')
    btn.addEventListener('click', function() {
      const x = new XMLHttpRequest()
      // 同源 所以此处的url可以简写
      x.open('GET', '/data')
      x.send()
      x.onreadystatechange = function() {
        if(x.readyState === 4) {
          if(x.status >=200 && x.status < 300) {
            console.log(x.response)
          }
        }
      }
        
    
    })
  </script>
</body>
</html>
const express = require('express')

const app = express()

app.get('/home', (request, response) => {
  // 响应一个页面
  response.sendFile(__dirname + '/index.html')
})

app.get('/data', (request, response) => {
  
  response.send('用户数据')
})
app.listen(9000, () => {
  console.log('服务已经启动....')
})

如何解决跨域

jsonp

JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明
才智开发出来,只支持 get 请求。

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

原生jsonp实践

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <input type="text">
  <p></p>

  <script>
    const ipt = document.querySelector('input')
    const p = document.querySelector('p')

    // 声明handle函数
    function handle(data) {
      ipt.style.border = 'solid 1px #fee'
      p.innerHTML = data.msg
    }

    ipt.addEventListener('blur', function() {
      let username = this.value
      // 如果有后台数据 用username与其比对
      // 1.创建script标签
      const script = document.createElement('script')
      // 2.设置标签的src属性
      script.src = 'http://localhost:8000/jsonp-server'
      // 3.将script标签添加到文档中
      document.body.appendChild(script)
    })
  </script>
</body>
</html>
app.all('/jsonp-server', (request, response) => {
  const data = {
    exit: 1,
    msg: '用户名已存在'
  }
  let str = JSON.stringify(data)
  response.end(`handle(${str})`)
})

jquery发送jsonp

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #result {
      width: 300px;
      height: 150px;
      border: solid 1px skyblue;
    }
  </style>
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
  
</head>
<body>
  <button>点击发送 jsonp请求</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},
          校区:${data.school}
        `)
      })
    })
  </script>
</body>
</html>
app.all('/jquery-jsonp-server', (request, response) => {
  const data = {
    name: '吉林大学',
    school: ['南面', '北面', '东面', '西面']
  }
  // 接收callback参数
  let cb = request.query.callback
  let str = JSON.stringify(data)
  response.end(`${cb}(${str})`)
})

设置CORS响应头实现跨域

// 设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
app.get('/delay', (request, response) => {
  // 设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  // 设置响应体
  setTimeout(()=> {
    response.send('延时响应')
  }, 3000)
})
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lalaxuan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值