Ajax

Ajax简介

Ajax即Asynchronous Javascript And XML(异步JavaScript和[XML] [HTML]或 [XHTML] CSS, [JavaScript][DOM], XML, [XSLT] 以及最重要的[XMLHttpRequest] 使用Ajax技术网页应用能够快速地将增量更新呈现在[用户界面]上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作。

XML简介

W3school:学习网站。
https://www.w3school.com.cn/xml/xml_intro.asp

Ajax的特点
##### Ajax的优点:

-  可以无需刷新页面与服务端进行交互
-  允许根据用户的时间来更新部分的页面内容

##### Ajax的缺点:

- 没有浏览历史、不能回退
- 存在跨域问题
- SEO不友好
HTTP协议

HTTP:超文本传输协议。协议规定了浏览器和万维网服务器之间相互通信的规则、约定。

请求报文

格式与参数:

行	GET / URL /HTTP
头   HOST:xxx.com
    Cookie:name=lihui
	Content-type:application/x-www-form-urlencoded
	User-Agent:chrome 84
空行
体	username=admin&password=admin
响应报文
行	HTTP/1.1 200 OK
头	Content-type=text/html;charset=utf-8
	Content-length:2048
	Content-encoding:zip
空行
体	<html>
		<head>
		</head>
		<body>
			<h1>lihui</h1>
		</body>
	</html>

状态码

404

403

401

500

node.js的安装

官网下载->一直下一步安装->安装成功后->node -v检查是否安装成功。

express框架的安装:npm i express

express框架的使用

//express的基本使用
//1、引入express
const { response } = require('express');
const express  = require('express');
const { request } = require('http');

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

//3、创建路由规则
//request 是对请求报文的封装
//response 是对响应报文的封装
app.get('/',(request,response)=>{
    //设置响应
    response.send('Hello Express')
})

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

express 框架的运行

PS E:\practice_vue\Vue\express> node express.js
服务已经启动,8080端口监听中~~~~

浏览器响应结果:

1 个请求
已传输 177 B
13 B 项资源
完成用时:3 毫秒
DOMContentLoaded:24 毫秒
加载时间:26 毫秒
请求网址: http://127.0.0.1:8080/
请求方法: GET
状态代码: 304 OK
远程地址: 127.0.0.1:8080
引荐来源网址政策: strict-origin-when-cross-origin

测试Ajax发送get请求

<!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>Ajax发送get请求</title>

    <style>
        #result{
            width: 200px;
            height: 100px;
            border: solid 1px #90b;
        }
    </style>
</head>
<body>
    <button>点我发送请求</button>
    <div id="result"></div>
</body>
</html>
//express的基本使用
//1、引入express
const { response } = require('express');
const express  = require('express');
const { request } = require('http');

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

//3、创建路由规则
//request 是对请求报文的封装
//response 是对响应报文的封装
app.get('/',(request,response)=>{
    //设置响应头 设置允许跨域
    response.setHeader('Access-controll-Allow-Origin','*')
    //设置响应
    response.send('Hello Express')
})

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

从新启动js报错:(npm express.js)

Error: listen EADDRINUSE: address already in use :::8080
    at Server.setupListenHandle [as _listen2] (net.js:1318:16)
    at listenInCluster (net.js:1366:12)
    at Server.listen (net.js:1452:7)
    at Function.listen (E:\practice_vue\node_modules\express\lib\application.js:635:24)
    at Object.<anonymous> (E:\practice_vue\Vue\express\express.js:21:5)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
Emitted 'error' event on Server instance at:
    at emitErrorNT (net.js:1345:8)
    at processTicksAndRejections (internal/process/task_queues.js:80:21) {
  code: 'EADDRINUSE',
  errno: -4091,
  syscall: 'listen',
  address: '::',
  port: 8080
}

报错信息描述,端口被占用了,将启动的服务停止从新运行即可。

浏览器:Access-controll-Allow-Origin: *

完整代码

//express的基本使用
//1、引入express
const { response } = require('express');
const express  = require('express');
const { request } = require('http');

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

//3、创建路由规则
//request 是对请求报文的封装
//response 是对响应报文的封装
app.get('/express',(request,response)=>{
    //设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')
    //设置响应
    response.send('Hello Express')
})

//4、监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中~~~~")
})
<!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>Ajax发送get请求</title>

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

<body>
    <button>点我发送请求</button>
    <div id="result"></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://127.0.0.1:8000/express');
            //3、发送
            xhr.send();
            //4、事件绑定 处理服务端返回的结果
            //on when 当...的时候
            //readystate 是xhr对象中的一个属性、表示状态 0 1 2 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;
                    } else {

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

</html>

Ajax-Get设置请求参数

?a=100&b=200

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

Ajax发送post请求

//express的基本使用
//1、引入express
const { response } = require('express');
const express  = require('express');
const { request } = require('http');

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

//3、创建路由规则
//request 是对请求报文的封装
//response 是对响应报文的封装
app.post('/express',(request,response)=>{
    //设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')
    //设置响应
    response.send('Hello Express')
})

//4、监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中~~~~")
})
<!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>Ajax发送post请求</title>

    <style>
        #result{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
    <div id="result">

    </div>

    <script>
        //获取元素对象
        const result = document.getElementById('result');
        //绑定事件监听
        result.addEventListener('mouseover',function(){
           //1、创建对象
           const xhr = new XMLHttpRequest();
           //2、初始化、设置类型与URL
           xhr.open('post','http://127.0.0.1:8000/express');
           //3、发送
           xhr.send();
           //4、事件绑定
           xhr.onreadystatechange = function(){
               //判断
               if(xhr.readyState === 4){
                   if(xhr.status >= 200 & xhr.status < 300){
                       //处理服务端返回的结果
                       result.innerHTML = xhr.response;
                   }
               }
           }
        })
    </script>
</body>
</html>

Ajax-Post设置请求参数

xhr.open('post','http://127.0.0.1:8000/express');
xhr.send('a=100&b=200&c=300');
或
xhr.send('a:100&b:200&c:300');
或
xhr.send('123456');

Ajax设置请求头

xhr.setRequestHeader('预定义','value')

xhr.setRequestHeader('自定义','value')
//所有请求头信息都能获取
response.setHeader('Access-Control-Allow-Headers','*')
response.setHeader('Access-Control-Allow-Headers','*')
//可以接收所有请求 app.all
app.all('/express',(request,response)=>{
    //设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')
    //设置响应
    response.send('Hello Express')
})

Ajax请求服务端响应JSON数据

两种方式:手动转换和自动转换

//express的基本使用
//1、引入express
const { response } = require('express');
const express  = require('express');
const { request } = require('http');

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

//3、创建路由规则
//request 是对请求报文的封装
//response 是对响应报文的封装
app.all('/express',(request,response)=>{
    //设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')
    //响应头
    response.setHeader('Access-Control-Allow-Headers','*')
    //响应一个数据
    const data = {
        name:'lihui',
    }
    //对对象进行字符串转换
    let str = JSON.stringify(data);
    //设置响应
    response.send(str)
})

//4、监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中~~~~")
})
<!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: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
    <div id="result"></div>

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

自动重启工具的安装

这个在安装vscode的时候也可以选择:

安装命令(npm install -g nodemon

浏览器的缓存问题:(浏览器会对Ajax发送的数据进行缓存,有时候,测试更新时,会造成干扰。)

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

//延迟响应
setTimeout(()=>{
	//设置响应体
	respon.send('延时响应');
},3000)
//超时设置
xhr.timeout = 2000;
//超时回调
xhr.ontimeout = function(){
	alert('网络超时,请重试~~~');
}
//网络异常问题
xhr.onerror = function(){
	alert('你的网络好像出现了问题~~~');
}

Ajax取消请求

//获取元素对象
const btns = document.querySelectorAll('button');
btns[0].onclick = function(){
	const x = new XMLHttpRequest();
	x.open('GET',"http://127.0.0.1:8000/express");
	x.send();
}

//abort
btns[1].onclick = function(){
    alert("手动取消Ajax请求")
    x.abort();
}

Ajax重复请求发送问题

用户频繁发送请求,服务器压力就大,解决服务器压力大的问题。

//标识变量
let isSending = false;//是否正在发送Ajax请求
//获取元素对象
const btns = document.querySelectorAll('button');
btns[0].onclick = function(){
    if(isSending) x.abort();//如果正在发送,则取消该请求,创建一个新的请求。
	const x = new XMLHttpRequest();
	x.open('GET',"http://127.0.0.1:8000/express");
	x.send();
    //判断是否正在发送Ajax请求
    x.onreadystatechange = function(){
        if(x.readyState === 4){
            //修改标识变量
            isSending = false;
        }
    }
}
jQuery中的Ajax请求

搜索bootcnd
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
引入jQuery

https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<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>
    //get
	$('button').eq(0).click(function(){   
        $.get('http://127.0.0.1:8000/express',{a:100,b:200},function(data){
            console.log(data);
        },'json');
    })
    //post
    $('button').eq(1).click(function(){   
        $.get('http://127.0.0.1:8000/express',{a:100,b:200},function(data){
            console.log(data);
        },'json')
     })
    //通用
    $('button').eq(2).click(function(){
        $.ajax({
            //url
            url:'http://127.0.0.1:8000/express',
            //参数
            data:{a:100,b:200},
            //请求类型
            type:'GET',
            //响应体结果设置(post请求设置)
            dataType:'json',
            //成功的回调
            sucess.function(data){
            	console.log("成功~~~~");
    	    }
        	//失败的回调
        	error.function(data){
                console.log("出错了~~~")
            }
        	//头信息
        	headers:{
                c:300,
                d:400
            }
        })
    })
</script>

jQuery学习文档

https://jquery.cuishifeng.cn/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4gEBNLrY-1662470493263)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1662465349297.png)]

Axios发送Ajax请求

学习网址

https://github.com/axios/axios

使用安装命令:(npm install axios)

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
//国外连接访问时比较慢可以换成bootcdn
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.js"></script>

在这里插入图片描述

https://www.axios-http.cn/docs/intro
在这里插入图片描述

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

<script>
	const btns = document.querySelectorAll('button');
    btns[0].onclick = function(){
        //GET请求
        axios.get('http://127.0.0.1:8000/express',{
            //url参数
            params:{
                id:100,
                vip:7
            },
            //请求头信息
            headers:{
                name:'lihui',
                age:18
            }
        }).then(value=>{
            console.log(value);
        });
    }
    
    btns[0].onclick =function(){
        axios.post('/express', //url
           //设置请求体
           {
            	username:'lihui',
            	password:'lihui',
        	},{
            params:{
                id:200,
                vip:1
            },
            //请求头参数
            headers:{
                heigth:100,
                weight:90,
            }
        })
    }
</script>

axios通用方式发送Ajax请求

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

axios通过函数发送Ajax请求

<button>ajax请求</button>

<script>
	const btn = document.querySelector('button');
    btn.onclick = function(){
        fetch('http:127.0.0.1:8000/express?vip=10',{
            //请求方法
            method:'POST',
            //请求头
            headers:{
                name:'lihui'
            },
            //请求体
            body:'username = adming & password = admin',
        }).then(response=>{
			return response.text();//text可以换成json对象
        }).then(response=>{
            console.log(response);
        });
    }
</script>
跨域
同源策略

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>首页</title>
</head>
<body>
    <h1>lihui</h1>
    <button>点击获取用户数据</button>

    <script>
        const btn = document.querySelector('button');
            btn.onclick = 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 { response } = require('express');
const express = require('express');
const { request } = require('http');

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:仅支持get请求
  • CORS:跨域资源共享。

Ajax的实战

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐