原生AJAX入门及http报文入门

image-20221001152249505

AJAX

AJAX全称为Asynchronous JavaScript And XML,就是异步的Js和 XML。
通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

XML可扩展标记语肓。
XML被设计用来传输和存储数据。
XML和 HTML类似,不同的是HTML中都是预定义标签,而xML中没有预定义标签,全都是自定义标签,用来表示一些数据。

现在已经被JSON取代

AJAX的优点

1)可以无需刷新页面而与服务器端进行通信。
2)允许你根据用户事件来更新部分页面内容。

AJAX的缺点

1)没有浏览历史,不能回退

2)存在跨域问题(同源)

3)SEO不友好

HTTP请求报文

行	GET请求体空,POST都可 /S   HTTP/1.1

头	Host:
	 Cookie:
	 Content-type:
	 user-Agent:

空行

体	username = admin & password = admin

HTTP响应报文

行	HTTP/1.1 200 OK

头	Content-Type:
	 Content-length:2048
	 content-encoding:gzip

空行

体   响应体 HTML	

​ 下载node.js 并安装

​ npm init --yes初始化

​ VS终端中npm i express 安装express框架

image-20221001155210650

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

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

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

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

终端中输入node 文件名.js运行

前端HTML代码

<!DOCTYPE html>
<html lang = "en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>AJAX GET 请求</title>
    </head>
    <style>
        #result{
            width: 300px;
            height: 100px;
            border: solid 1px rgb(255, 0, 0);
        }
    </style>
    <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/server');
                //3.发送
                xhr.send();
                //4.事件绑定,处理服务端返回结果
                //readystate 是xhr对象属性,分别有0.1.2.3.4状态
                xhr.onreadystatechange = function(){
                    //判断(服务端返回所有结果)
                    if(xhr.readyState === 4){
                        if(xhr.status >= 200 && xhr.status < 300 ){
                            //处理,2xx返回成功
                            //响应
                            /* console.log(xhr.status);
                            console.log(xhr.statusText);
                            console.log(xhr.getAllResponseHeaders());
                            console.log(xhr.response); */
                            
                            //设置 result 文本
                            result.innerHTML = xhr.response;
                        }else{

                        }
                    }
                }
                //console.log('test');
            }
        </script>
    </body>
</html>

JS AJAX逻辑

//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 AJAX');
})

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

设置URL参数

问号分割地址,&分割其他参数

http://127.0.0.1:8000/server?a=200&b=50

发送POST请求

鼠标放入DIV时候发送请求并显示在框中

<!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: 100px;
            border: solid 1px #f00;
        }
    </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/server');
            //3.发送
            xhr.send();
            xhr.onreadystatechange  = function(){
                //判断
                if(xhr.readyState === 4){
                    if(xhr.status >= 200 && xhr.status < 300){
                        result.innerHTML = xhr.response;
                    }
                }
            }
            //console.log("test111")
        });
    </script>
</body>
</html>

server.js 加上app.post

//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 AJAX');
})

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

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

POST 请求设置参数

在send函数中设置参数,注意前面的GET是在open中问号隔开参数

xhr.send('a=100&b=50');

请求体格式比较灵活,只要后端能处理你的请求数据,比如可以请求图片,前端格式什么的。。

设置请求头信息

open后设置

xhr.open('POST','http://127.0.0.1:8000/server');
//设置请求头
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');

上面是HTTP头中预定义,查询字符类型

可以自定义非标准HTTP协议中请求头,需要后端支持,发送到后端

app.post改成.all并加上

//可接受全部响应头
	response.setHeader('Access-Control-Allow-Header','*')

服务端响应JSON数据

推荐用自动转换JSON类型

<!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>JSON响应</title>
    <style>
        #result{
            width: 200px;
            height: 100px;
            border: solid 1px #f00;
        }
    </style>
</head>
<body>
    <div id="result"></div>
    <script>
        const result = document.getElementById('result');
        //绑定事件
        window.onkeydown = function(){
            //发送请求
            const xhr = new XMLHttpRequest();
            //设置响应体数据类型 自动转换JSON数据
            xhr.responseType = 'json';
            //初始化
            xhr.open('GET','http://127.0.0.1:8000/json-server');
            //发送
            xhr.send();
            //事件绑定
            xhr.onreadystatechange  = function(){
                //判断
                if(xhr.readyState === 4){
                    if(xhr.status >= 200 && xhr.status < 300){
                        //自动转换
                        result.innerHTML = xhr.response.name;
                        /* 服务器返回字符串,手动转化
                        let data = JSON.parse(xhr.response);
                        console.log(data);
                        result.innerHTML = data.name; */

                        /* console.log(xhr.response);
                        result.innerHTML = xhr.response; */
                    }
                }
            }
            //console.log('test222');
        }
    </script>
</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 AJAX');
})

app.all('/json-server',(request,response)=>{
	//设置相应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
	//可接受全部响应头
	response.setHeader('Access-Control-Allow-Header','*')
	const data = {
		name:"KUN.A.A"
	}
	//send只接受字符串和buffer,需要字符串转换
	var str = JSON.stringify(data);
    //设置允许跨域
	response.send(str);
})

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

nodemon自动重启文件变化启动服务

终端中输入

npm install -g nodemon

服务启动改成

nodemon xxxx.js

改后端JS代码不用重启

附录

如果出现无法使用nodemon

终端输入此命令解决

set-ExecutionPolicy RemoteSigned

IE缓存问题

IE虽然淘汰了,但这个缓存问题还是值得一看的

在多次发送与接受数据后,AJAX缓存可能会影响返回的结果

IE中默认加载缓存

需要在.open中加上参数

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

原理:加上获取时间后,每次获取的时间戳不同,IE便不会加载缓存

<!DOCTYPE html>
<html lang = "en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>IE 缓存问题</title>
    </head>
    <style>
        #result{
            width: 300px;
            height: 100px;
            border: solid 1px rgb(255, 0, 0);
        }
    </style>
    <body>
        <button>点击发送请求</button>
        <div id = "result"></div>
        <script>
            const btn = document.getElementsByTagName("button")[0];
            const result = document.querySelector('#result');
            btn.addEventListener('click',function(){
                const xhr = new XMLHttpRequest();
                xhr.open('GET','http://127.0.0.1:8000/IE-server?='+Date.now());
                xhr.send();
                xhr.onreadystatechange = function(){
                    if(xhr.readyState === 4){
                        if(xhr.status >= 200 &&xhr.status < 300){
                            result.innerHTML = xhr.response;
                        }
                    }
                }
                //console.log('test2111');
            })
        </script>
    </body>
</html>
//IE缓存
app.get('/IE-server',(request,response)=>{
	//设置相应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //设置允许跨域
	response.send('HELLO IE');
})

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

//超时设置
xhr.timeout = 2000;
//超时回调
xhr.ontimeout = function(){
	alert("连接超时,请检查网络");
}
//网络异常回调
xhr.onerror = function(){
	alert("网络异常,请检查网络");
}
//延时相应,模拟超时
app.get('/delay',(request,response)=>{
	//设置相应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
	setTimeout(() => {
		response.send('HELLO IE');
	}, 3000);
})

HTML完整代码

<!DOCTYPE html>
<html lang = "en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>超时处理</title>
    </head>
    <style>
        #result{
            width: 300px;
            height: 100px;
            border: solid 1px rgb(255, 0, 0);
        }
    </style>
    <body>
        <button>点击发送请求</button>
        <div id = "result"></div>
        <script>
            const btn = document.getElementsByTagName("button")[0];
            const result = document.querySelector('#result');
            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){
                            result.innerHTML = xhr.response;
                        }
                    }
                }
                //console.log('test2111');
            })
        </script>
    </body>
</html>

实际开发中alert过于激进,超时回调中多用DIV调用或者遮罩层

image-20221002181556990

设置浏览器为离线状态

AJAX取消请求

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

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

记得 let x = null 因为处于不同局部变量中

同时x 不能设置为const

请求重复发送问题

防止用户在网络差时多次请求增加服务端压力。

防抖节流

设置一个标识变量即可,当标识变量说明正在发送时直接取消,创建新请求

		//获取元素对象
        const btns = document.querySelectorAll('button');
        var x = null;
        //标识变量
        let flag = false;
        btns[0].onclick = function(){
            //判断标识变量
            if(flag)//如果正在发送,直接取消,创建一个新请求
                x.abort();
            x = new XMLHttpRequest();
            //修改标识变量值
            flag = true;
            x.open('GET','http://127.0.0.1:8000/delay');
            x.send();
            x.onreadystatechange = function(){
                if(x.readyState === 4){
                    //修改标识变量
                    flag = false;
                }
            }
        }

        //abort 取消请求
        btns[1].onclick = function(){
            x.abort();
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Kun.A.A

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

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

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

打赏作者

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

抵扣说明:

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

余额充值