ajax

一、ajax的五个步骤


ajax技术有专门的固定的步骤过程,必须严格按照ajax的步骤过程执行

第一步:使用ajax构造函数创建ajax实例化对象对象

              const  xhr = new XMLHttpRequest();

第二步:通过 ajax对象的open() 方法,设定 请求方式 和 请求地址

               ajax对象.open(参数1 ,  参数2);

                   参数1 请求的方式  get / post

                   参数2 请求的url地址路径

               如果是get方式,可以携带请求参数

                   xhr.open('get' , 'url地址?键名=键值&&键名=键值...');

               如果是post方式,不可以携带请求参数

                   xhr.open('post , 'url地址'');

第三步:如果是post请求方式,必须要设定请求头格式

               xhr.setRequestHeader('Content-Type' , 'application/x-www-form-urlencoded');

第四步:通过 ajax对象的send() 方法,发送ajax请求

               按照ajax对象.open() 设定的 请求方式 和 请求url地址 发送 请求

               get方式:xhr.send();

               post方式:xhr.send('键名=键值&键名=键值...');

               post方式携带的参数要写在ajax对象的send() 方法里

第五步:接收ajax请求结果

               根据结果 动态渲染生成页面

               ajax对象.onload是ajax请求结束执行的函数程序,ajax请求是一个异步程序会执行所有的同步程序,执行完成之后,再执行异步的ajax请求

               xhr.onload = function(){

                      在 xhr.response 或者  xhr.responseText 中 存储 响应体结果

                      如果是 json字符串 使用 JSON.parse() 还原为对应的数据结构

              }
二:前后端交互


    其实就是一个前后端通讯, 是我们在开发中, 必不可少的一个技能
    目前我们用到的技术就是 ajax
    流程为 在前端开发中, 在某一个时刻(页面首次打开渲染的时候, 或者点击下一页需要新的数据的时候)
        此时通过 ajax 向后端(服务端)发送一个请求, 拿到 所谓的数据
    发送请求需要传一些参数(就是告诉后端你要什么东西), 如果你不知道, 那么问你的组长要一个 '接口文档'

三:实现一个 ajax 请求

// 1. 创建一个 ajax 对象
const xhr = new XMLHttpRequest()
// 2. 配置 ajax 对象
// xhr.open('请求的方式(不区分大小写)', '请求的地址', '一个布尔值')
xhr.open('GET', 'http://localhost:8888/test/first', true)
// 3. 发送请求
xhr.send()
// 4. 接收响应
xhr.onload = function () {
    // console.log('现在后端已经给我们返回了 我们想要的数据了')
    console.log(xhr.responseText)   // 哇塞, 你已经成功使用 ajax 发送给我了一个请求, 这是我给你的
回应, 我是一个字符串类型 ^_^ !
}

四: ajax 的异步问题


    ajax 是否异步为 第二步配置的第三个参数决定的, 也就是那个布尔值
        默认为 true 代表的是开启异步, 如果传递的是 false 代表关闭异步开启同步
    同步和异步的差别
        1. 创建一个 ajax 对象   (同步代码)
        2. 配置对象             (同步代码, 但是第三个参数决定了 下一步是否为异步)
        3. 发送请求             (根据上一步的配置, 才能看出是否为异步)
        4. 接受响应             (同步代码)
        => 如果传递的是 true 或者没有传递, 那么为异步, 此时的运行流程
            1. 创建一个对象
            2. 配置对象
            3. 发送请求
            4. 接收响应
            5. 响应完成了
        
        => 如果传递的是 false, 那么为同步, 此时的运行流程
            1. 创建一个对象
            2. 配置对象
            3. 发送一个请求, 等待请求完成后, 开始执行后边的代码
            4. 接收响应 (前边三步已经把这个请求完全的运行结束了, 所以此时不可能再触发这个函数了)

 => 如果传递的是 false, 那么为同步, 此时的运行流程
     1. 创建一个对象
     2. 配置对象
     4. 接收响应, 等到请求完成的时候, 会触发
     3. 发送一个请求, 等待请求完成后, 开始执行后边的代码
 如果传递是异步, 可以按照 1234的流程书写(1243也可以)
 如果传递的是同步, 必须按照 1243 的流程书写
         所以在开发的时候, 为了方便起见, 一般都会书写为 1243

// 1. 创建一个 ajax 对象
const xhr = new XMLHttpRequest()
// 2. 配置 ajax 对象
xhr.open('GET', 'http://localhost:8888/test/first', false)
// 4. 接收响应
xhr.onload = function () {
    // console.log('现在后端已经给我们返回了 我们想要的数据了')
    console.log(xhr.responseText)   // 哇塞, 你已经成功使用 ajax 发送给我了一个请求, 这是我给你的
回应, 我是一个字符串类型 ^_^ !
}
// 3. 发送请求
xhr.send()

五: http 传输协议(了解)

         * 
     还有一个协议 https, 相对于 http 安全一点点
         * 
     根据传输协议规定, 必须是由前端向后端发送请求, 发送请求的时候如果要携带一些参数, 必须是字符串格式

 1. 建立连接
     浏览器和服务端 建立一个连接
 2. 发送请求
     要求前端必须以 '请求报文' 的形式发送;
     请求报文 由 浏览器进行组装, 我们只需要提供对应的信息即可;
     比如说: 请求的方式, 请求的地址, 请求需要的参数
 3. 接收响应
     要求后端必须以 '响应报文' 的形式返回;
     响应报文内有一个东西叫做响应状态码;
 4. 断开连接
     浏览器和服务端的连接断开
 响应状态码
     100~199     表明连接还在继续
     200~299     表明连接各种成功   但现在只会返回一个 200
     300~399     表明请求重定向
     400~499     表明请求失败        但现在只会看到一些 403 404 401 400  一般4开头是前端的问题       500~599     表明服务端出错      跟前端无关, 是后端的问题

六、ajax 的状态码
    通过一个数字, 表明 ajax 当前运行到那一步了
    0: ajax 创建成功
    1: 当前 ajax 配置成功
    2: 当前 ajax 发送成功
    3: 当前 浏览器 正在解析服务端返回给我们的内容
            如果返回的内容少, 这一步基本能接受完
            如果返回的内容多, 这一步接收的是不完整的
    4: 表明 浏览器 已经把服务端返回的内容 全都解析完毕了~

// 1. 创建一个 ajax 对象
const xhr = new XMLHttpRequest()
// console.log(xhr.readyState) // 0
// 2. 配置 ajax 对象
xhr.open('GET', 'http://localhost:8888/test/first')
// console.log(xhr.readyState) // 1
// 4. 配置接收响应的函数
// xhr.onload = function () {
//     console.log(xhr.responseText)
// }
// 3. 发送请求
xhr.send()
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        console.log('当前浏览器已经完全解析完毕 返回的数据', xhr.responseText)
    }
}
// xhr.onreadystatechange = function () {
//     if (xhr.readyState === 2) {
//         console.log('当前 请求 发送成功', xhr.responseText)
//     } else if (xhr.readyState === 3) {
//         console.log('当前浏览器正在解析返回的数据, 可能没完成', xhr.responseText)
//     } else if (xhr.readyState === 4) {
//         console.log('当前浏览器已经完全解析完毕 返回的数据', xhr.responseText)
//     }
// }

七: 请求方式的区别

 get 偏向于获取的语义    (商品列表数据, 用户详情, 商品详情)
     delete  偏向于获取的语义    (删除某一个内容)
 post    偏向于修改的语义    (修改用户名, 修改密码)
     put     偏向于修改的语义    (修改库存, 修改收藏数量)
 等等.....
 现在 市面公司中常用的方式只有两个, get/post
 请求方式不同, 会导致传参的方式不同, 除此之外对我们前端来说没有区别
     => get: 直接将需要传递参数拼接在路径后即可, 注意使用 ? 间隔
             `http://localhost:8888/test/first?key=value`
             `http://localhost:8888/test/first?key=value&key2=value2`
     => post: 也是需要传递字符串, 只不过不在放在 地址路径后, 而是放在 请求体内书写(其实就是 xhr.send())

 在传参的时候还需要配置一个请求头中的属性 content-type
 content-type 赋值的时候, 还要区分我们传递的是普通字符串, 还是 json 格式的字符串

  普通字符串: xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')

 json字符串: xhr.setRequestHeader('content-type', 'application/json')

八:分页版 ajax 

// 0. 获取元素
var oUl = document.querySelector('ul')  // ul 标签, 内部放 商品的 li
var total = document.querySelector('.total')    // 页码标签
var prev = document.querySelector('.prev')  // 上一页按钮
var next = document.querySelector('.next')  // 下一页按钮
var oSelect = document.querySelector('select')  // 选择框
// 0. 准备变量
var currentNum = 1  // 默认当前页 为 第 1 页
var pageSize = 4    // 默认打开时 每页展示 4 条数据
var totalNum = 0    // 记录一下总页码
// 0. 像后端发送请求, 拿到对应的数据
function myAjax() {
    // 0.1 创建一个 ajax 对象
    const xhr = new XMLHttpRequest()
    // 0.2 配置 ajax 对象
    xhr.open('GET', `http://localhost:8888/goods/list?current=${currentNum}&pagesize=$
{pageSize}`)
    // 0.3 配置接收响应的函数
    xhr.onload = function () {
        const res = JSON.parse(xhr.responseText)
        totalNum = res.total
        myFn(res.list)
    }
    // 0.4 发送请求
    xhr.send()
}
// 首次打开页面的时候, 发送请求
myAjax()
// 0. 准备一个渲染函数
function myFn(list) {
    oUl.innerHTML = list.reduce(function (prev, item) {
        return prev + `
            <li>
                <img src="${item.img_big_logo}" alt="">
                <p>${item.title}</p>
                <p>城市: ${item.city}</p>
                <p>地址: ${item.address}</p>
                <p>价格: ${item.price}</p>
                <p>时间: ${item.showTime}</p>
            </li>`
    }, '')
    // 0.2 调整页码信息
    total.innerHTML = `${currentNum} / ${totalNum}`
    // 0.3 处理按钮
    currentNum === 1 ? prev.classList.add('disable') : prev.classList.remove('disable')
    currentNum === totalNum ? next.classList.add('disable') : next.classList.remove
('disable')
}
// 2. 点击下一页
next.onclick = function () {
    if (currentNum === totalNum) return // 如果是在最后一页, 那么拦截函数执行
    // 如果执行到这个位置, 当前页一定不是最后一页
    currentNum++
    myAjax()
}
// 3. 点击上一页
prev.onclick = function () {
    if (currentNum === 1) return    // 如果是在第一页, 那么拦截函数执行
    // 如果执行到这个位置, 当前页一定不是第一页
    currentNum--
    myAjax()
}
// 4. 改变每页展示数据
oSelect.onchange = function () {
    // 当选择框内部的 options 改变的时候执行
    pageSize = oSelect.value
    myAjax()
}

九:封装 ajax

    小问题: 如果让你封装, 你需要处理些什么? 比如参数需要些什么?
参数:
    1. 请求的方式: 选填, 默认值为 GET;  形参名: type
    2. 请求的地址: 必填;    形参名: url
    3. 请求为同步还是异步: 选填, 默认值为 true; 形参名: async
    4. 请求需要携带参数: 选填, 默认为 '';   形参名: data
返回值:
    需要返回一个 promise 对象, 后续可以通过 .then 或者 async/await 去使用

 //封装异步代码:回调函数,promise

 function myAjax(options) {}    //接收一个对象options
 myAjax({     //绑定默认值
     url: 'http:xxx',
     async: false,
     data: 'name=zhangsan'
 })

     小问题: 如果让你封装, 你需要处理些什么? 比如参数需要些什么?
参数:
    1. 请求的方式: 选填, 默认值为 GET;  形参名: type
    2. 请求的地址: 必填;    形参名: url
    3. 请求为同步还是异步: 选填, 默认值为 true; 形参名: async
    4. 请求需要携带参数: 选填, 默认为 '';   形参名: data
返回值:
    需要返回一个 promise 对象, 后续可以通过 .then 或者 async/await 去使用

function myAjax(options) {
    // 1. 验证 参数中的 url 必传
    if (options.url === undefined) throw new Error('参数中缺少必传项 url')  // 返回一个错误
    // 1.1 参数格式验证, 拿请求方式举例: type 只接受 undefined 或者 string 两种类型
    //console.log('options.type') 如果没传值那么结果是undefined,如果传了就是字符串类型
    //options.type === undefined || typeof(options.type) === 'string'  不是没传就是传了strng

    if (!(options.type === undefined || typeof(options.type) === 'string')) throw new Error(
参数中 type 的类型必须为 string')
    // 1.2 补全剩余参数的格式校验
    if(!(options.url === undefined || typeof(options.url) === 'string')) throw new Error('ur
中参数的类型必须为string')
    if(!(options.data === undefined || typeof(options.url) === 'data')) throw new Error('dat
中参数的类型必须为string')
    if(!(options.asynce === undefined || typeof(options.url) === 'asynce')) throw new Error
('asynce中参数的类型必须为string')
    // 2. 封装默认值
    const _options = {
        url: options.url,
        type: options.type || 'GET',  //如果不传参结果为undefined,那么返回GEF。如果转入的值
那么返回自己
        data: options.data || '',
        // 空值检测符, 该符号的特点 只会在 左侧的值为空值的时候返回右侧, 比如左侧为: null, 
undefined
        async: options.async ?? true
    }
    // 请求的参数还没处理, 后续需要继续完善
    const xhr = new XMLHttpRequest()
    xhr.open(_options.type, _options.url, _options.async)
    xhr.onload = function () {
        console.log(xhr.responseText)
    }
    xhr.send()
}
myAjax({
    url: 'http://localhost:8888/test/first',  
    //async:false,   //看默认值是否封装过去
})

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值