• 网络-Ajax




    前言

    本文主要记录Ajax技术的简介,以及用法。


    一、Ajax

    Ajax是一组用于在Web浏览器和Web服务器之间进行异步通信的Web开发技术。
    它代表着Asynchronous JavaScript and XML(异步JavaScript和XML),尽管XML并不总是作为数据格式使用。
    通过Ajax,Web应用程序可以在不重新加载整个页面的情况下更新页面的部分内容。这样可以实现更加交互和响应式的用户体验。
    Ajax使用JavaScript发送请求到服务器并异步处理响应,而不会阻塞用户界面。
    可以通过 JavaScript 和XNLHttpRequest对象来向服务器请求数据

    Ajax可以用于执行各种任务,例如从服务器检索数据、提交表单数据和动态更新内容。
    它通常用于现代Web应用程序中,用于创建自动完成搜索框、实时更新和无限滚动等交互功能。

    优点:

    • 提高用户体验:通过减少页面重载和刷新,使得网站变得更加灵活和动态
    • 减轻服务器负载:可以有效减少服务器接收到的请求次数和需要响应的数据量,从而减轻服务器负担
    • 提高响应速度:可以异步获取数据并更新页面,从而提高响应速度
    • 增加交互:使页面变得可交互性

    缺点:

    • 对搜索引擎优化(SEO)不友好,爬虫无法抓取Ajax中的内容与URL ===>考虑用SSR服务端渲染技术
    • 需要考虑安全性问题,数据和网络安全需要采取对应的措施

    二、使用步骤

    XNLHttpRequest对象

    • 创建对象xhr:
    const xhr = new XMLHttpRequest()
    
    • 1
    • open方法:接收三个参数分别是 请求方式、请求地址、是否异步:默认为true
     xhr.open('post','http://localhost:3000/api/post',true)
    
    • 1
    • setRequestHeader方法:用于为请求的HTTP头设置值。
    setRequestHeader("header", "value")
    
    • 1
    • onreadystatechange方法:监听服务端返回的数据
    xhr.onreadystatechange = () =>{
                console.log(xhr)
                if (xhr.readyState === 4 && xhr.status === 200) {
                    console.log(xhr.responseText)
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    onreadystatechange

    • readyState属性:
      • 0:未初始化,XNLHttpRequest已经创建,但未调用open方法
      • 1:已打开,open方法已调用,send方法未调用
      • 2:已发送,send方法已调用,服务端接收到请求
      • 3:正在接收,服务器正在处理请求并返回数据
      • 4:完成,服务端已完成数据传输
    • status属性: 200成功 400参数错误 403没有权限 401token找不到 404未找到 500服务器错误
    • send方法:给服务端发送的数据
    xhr.send(JSON.stringify({name:'smz'}))
    
    • 1

    send

    • abort方法:用于停止或放弃当前异步请求。必须在open方法后,无法恢复。
    stop.addEventListener('click',()=>{
                xhr.abort()
            })
    
    • 1
    • 2
    • 3
    • getResponseHeader方法:用于以字符串形式返回指定的HTTP头信息。
    getResponseHeader("headerLabel")
    
    • 1
    • getAllResponseHeaders方法:用于以字符串形式返回完整的HTTP头信息。
     getAllResponseHeaders()
    
    • 1

    获取请求头

    • 监听进度:

      给xhr对象添加一个progress事件,返回event

      event.loaded:当前进度
      event.total:总进度

     xhr.addEventListener('progress',(event)=>{
                console.log(event.loaded,event.total)
            })
    
    • 1
    • 2
    • 3

    进度
    进度

    • 设置超时:xhr.timeout = 3000

    • 超时回调:监听timeout事件

     xhr.addEventListener('timeout',()=>{
                alert('请求超时')
            })
    
    • 1
    • 2
    • 3

    超时

    • 中断回调:监听abort事件
     xhr.addEventListener('abort',()=>{
                console.log('请求中断')
            })
    
    • 1
    • 2
    • 3
    • 监听load事件:也可以监听请求是否成功,就不用判断readyState的值
     xhr.addEventListener('load',()=>{
                if (xhr.status === 200){
                    console.log('请求成功,触发onload')
                }
            })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    请求成功

    • post请求:请求参数要放在send()中

    完整代码

    前端代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div>
        <button id="send">发送请求</button>
        <button id="stop">中断请求</button>
        <div>进度条<span id="progress"></span></div>
        <input id="file" type="file">
    </div>
    </body>
    <script>
        let btn = document.getElementById('send')
        let file = document.getElementById('file')
        btn.addEventListener('click',()=>{
            sendAjax()
        })
        //上传文件
        file.addEventListener('change',()=>{
            const formData = new FormData()
            formData.append('file',file.files[0]) // key值对应后端 upload.single('file')
            const xhr = new XMLHttpRequest()
            xhr.open('post','http://localhost:3000/api/upload',true)
            xhr.onreadystatechange = () =>{
                console.log(xhr)
                if (xhr.readyState === 4 && xhr.status === 200) {
                    console.log(xhr.responseText)
                }
            }
            xhr.send(formData)
        })
        const sendAjax = () =>{
            const xhr = new XMLHttpRequest()
            // 三个参数,请求方式、请求地址、是否异步:默认为true
            //get
            // xhr.open('get','http://localhost:3000/api/txt?name=smz',true)
            //post
            xhr.open('post','http://localhost:3000/api/post',true)
            //设置请求头
            xhr.setRequestHeader('Content-Type','application/json')
            //设置超时
            xhr.timeout = 30000
            //超时回调
            xhr.addEventListener('timeout',()=>{
                alert('请求超时')
            })
            // 监听服务端返回的数据
            xhr.onreadystatechange = () =>{
    
                if (xhr.readyState === 4 && xhr.status === 200) {
                    console.log(xhr.responseText)
                }
            }
            //监听进度
            xhr.addEventListener('progress',(event)=>{
                const progress = document.getElementById('progress')
                progress.innerText = `${(event.loaded/event.total*100).toFixed(2)}%`
                console.log(event.loaded,event.total)
                //响应头
                console.log(xhr.getAllResponseHeaders())
                console.log(xhr.getResponseHeader('content-type'))
            })
            //中断请求
            let stop = document.getElementById('stop')
            stop.addEventListener('click',()=>{
                xhr.abort()
            })
            //监听中断
            xhr.addEventListener('abort',()=>{
                console.log('请求中断')
            })
            //监听请求成功
            xhr.addEventListener('load',()=>{
                if (xhr.status === 200){
                    console.log('请求成功,触发onload')
                }
            })
            // 给服务端发送的数据
            // xhr.send(null)
            //post
            xhr.send(JSON.stringify({name:'smz'}))
        }
    
    </script>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    后端代码:这里用的node

    const express = require('express')
    const app = express()
    const multer = require('multer')
    
    const single = multer.diskStorage({
        destination: (req, file, cb) => {
            cb(null, './upload')
        },
        filename: (req, file, cb) => {
            cb(null, Date.now() + file.originalname)
        }
    })
    const upload = multer({
        single
    })
    
    app.get('/api/txt',(req,res)=>{
        res.setHeader('Access-Control-Allow-Origin','*')
        const {name} = req.query // 函数名
        let text = ''
        for(let i=0;i<10000;i++){
            text += `${name}Ajax`
        }
        res.send( text)
    })
    
    app.use(express.json())
    app.use(express.urlencoded({extended:true}))
    // post请求
    app.post('/api/post',(req,res)=>{
        res.setHeader('Access-Control-Allow-Origin','*')
        console.log(req.body)
        res.json({
            code:200,
            data:{
                name: req.body.name
            }
        })
    })
    // 预检请求放行
    app.options('/api/*', (req,res) => {
        res.setHeader("Access-Control-Allow-Origin","*")
        res.setHeader("Access-Control-Allow-Headers", "*");
        res.end()
    })
    
    //传文件
    app.post('/api/upload',upload.single('file'),(req,res)=>{
        console.log(req.file)
        res.setHeader('Access-Control-Allow-Origin','*')
        res.json({
            code:200
        })
    })
    
    app.listen(3000,()=>{
        console.log('server is running')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    总结

    axios第三方库对Ajax做了一些封装,本文主要记录了Ajax的介绍与使用。

  • 相关阅读:
    新风口:周星驰招聘要求的Web3.0技术到底是什么?
    【HCIE】VXLAN
    arm-2d头文件概述
    PyQt5安装详细教程
    flutter循环
    从原理到代码实践 | pytorch损失函数
    Web UI自动化测试框架
    【AI】第 1 章:你的深度学习之旅
    RoCE多网卡时,报文可以过去,但是回不来
    【MySql系列】深入解析数据库索引
  • 原文地址:https://blog.csdn.net/smznbhh/article/details/133448015