AJAX(express)

AJAX

释放端口 ctrl+c
自启动服务端 npx nodemon nidi.js
IE缓存问题解决:添加一个Date.now() 让它知道这是动态

XML 用来传输和保存数据(自定义标签)

目前已经被JSON取代

HTTP

超文本传输协议
HTTP请求报文格式
GET/POST /s?ie=utf-t(url) HTTP/1.1(版本)
Host: nidi.com
Cookie: name=nidi
Content-type: application/x-www-form-urlencoded
Use-Agent: chrome 83"
空行
GET请求体为空,POST请求体可以不为空

响应报文格式
HTTP协议版本 响应状态码 响应状态字符串

Content-type: text/html;charset=utf/8
Content-length: 2048
Content-encoding: gzip
空行
HTML语法内容

<html>
    <head>
    </head>
    <body>
    	<h1></h1>
    </body>
</html>

Express

//引入express
const express = require('express');
//创建应用对象
const app = express();
//创建路由规则
//request 是请求报文的封装
//response 是对响应报文的封装
app.get('/server', (request, response)=>{
//改成/server,当客户端浏览器发送请求时,url的路径是请求行的第二段的内容他的路径是/server,执行回调函数
    //设置响应头    设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    //设置响应
    response.send('hello ajax');
});
//监听端口启动服务
app.listen(8000, ()=>{
    console.log("服务已经启动,8000端口监听中");
});

释放端口 ctrl+c

请求基本操作

get请求操作

get请求体放在路径后面加?即可

<body>
    <button>点击提示信息</button>
    <div id="result"></div>
</body>
<script>
    const btn = document.getElementsByTagName('button')[0];
    btn.onclick = function(){
        console.log('test');
    //ajax操作  响应报文
    //1.创建对象
    const xhr = new XMLHttpRequest();
    //2.初始化 设置请求方法和url
    xhr.open('GET','http:/127.0.0.1:8000/server?a=100&b=200');
    //设置请求参数 ?a=100&b=200
    //3.发生
    xhr.send();
    //4.事件绑定
    //on when当..的时候
    //redystate 是xhr对象中的属性
    //状态0 1 2 3 4
    //0 表示未初始化
    //1 open方法调用完毕
    //2 send方法调用完毕
    //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;
            }
        }
    }
    }
</script>

const express = require('express');
const app = express();
app.get('/server', (request, response) => {
    //当客户端浏览器发送请求时,url的路径是请求行的第二段的内容他的路径是/server,执行回调函数
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.send('hello');
});
app.listen(8000, () => {
    console.log("服务已经启动,8000端口监听中");
});
POST请求操作

鼠标经过div发送Ajax请求,将请求体显示在div中
post请求体放在send()中

<body>
    <div id="result">放在上面提示信息</div>
</body>
<script>
    //获取元素对象
    const result = document.getElementById("result");
    //绑定事件
    //mouseover 当鼠标发放在上面时发送请求
    result.addEventListener("mouseover",function(){
        console.log("test");
        //1.创建对象
        const xhr = new XMLHttpRequest();
        //2.初始化 设置类型与URL
        xhr.open('POST', 'http://127.0.0.1:8000/server');
        //设置请求体
        
        //3.发送
        xhr.send('a=100&b=200');
        //post请求体放在send中
        //4.事件绑定
        xhr.onreadystatechange = function(){
            //判断
            if(xhr.readyState === 4){
                if(xhr.status >= 200 && xhr.status < 300){
                    //处理服务端返回结果
                    result.innerHTML = xhr.response;
                }
            }
        }
    
    })
</script>

const express = require('express');
const app = express();
app.post('/server', (request, response) => {
    //设置响应头    允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');  
    //设置响应体
    response.send('hello post');
});
app.listen(8000, () => {
    console.log("服务已经启动,8000端口监听中");
});

响应状态码返回404的原因
1.url设置出错 (http://)
2.网络出现波动,请求错误

设置头信息
//写在open后面
//设置请求头
//Content-Type设置请求体内容类型    第二个''参数查询字符串的类型(固定写法)
        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        //自定义 错误原因:在请求头中加入了自定义的头
        xhr.setRequestHeader('name','nidi');
		//解决方法:
//在js中加入 (设置自定义请求头服务器需设置)
//response.setHeader('Access-Control-Allow-Headers','*');
//并把类型变成all
const express = require('express');
const app = express();
app.all('/server', (request, response) => {
    //设置响应头    允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');  
   //响应头 可以自定义
    response.setHeader('Access-Control-Allow-Headers','*');
    //设置响应体
    response.send('hello post');
});
app.listen(8000, () => {
    console.log("服务已经启动,8000端口监听中");
});
服务端响应JSON数据

服务器响应也可以设置为一个数据发送过去,但是不能直接写,要通过JSON.stringify(数据)把数据转换为JSON字符串。因为resopnse.send()中只能写字符串

<div id="result">按下键盘按键反应</div>
    <script>
        const result = document.getElementById('result');
        //绑定键盘按下事件
        window.onkeydown = function(){
            //发送请求
            const xhr = new XMLHttpRequest();
            //设置响应体数据类型
            xhr.responseText = '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){
                        // console.log(xhr.response);
                        // result.innerHTML = xhr.response;
//页面拿到json响应体是无法直接识别的,需要将json字符串转化为js对象
                        //1.手动对数据转化
                        // let data = JSON.parse(xhr.response);
                        // console.log(data);
                        // result.innerHTML = data.name;
                        //2.自动对数据转换
                        //借助xhr.resopnseType = 'json';
                        //在上面设置响应体数据类型
                        console.log(xhr.response);
                        result.innerHTML = data.name;
                    }
                }
            }
        }
    </script>

const express = require('express');
const app = express();
app.all('/json-server', (request, response) => {
   //响应头
    response.setHeader('Access-Control-Allow-Headers','*');
    //响应一个数据
    const data = {
        name: 'nidi'
    };
    //对对象进行字符串转换
    let str = JSON.stringify(data);
    //设置响应体
    response.send(str);
});
app.listen(8000, () => {
    console.log("服务已经启动,8000端口监听中");
});

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

服务端写个定时器,3s之后发送给响应体

const express = require('express');
const app = express();
app.all('/delay', (request, response) => {
   //响应头
    response.setHeader('Access-Control-Allow-Headers','*');
    //延时响应 3s做出响应
    setTimeout(() => {
        //设置响应体
        response.send('延时响应');
    }, 3000);
    
});
app.listen(8000, () => {
    console.log("服务已经启动,8000端口监听中");
});

前端页面设置超时设置xhr.timeout = 2000
超时回调xhr.ontimeout 网络异常回调xhr.onerror

<button>点击发送</button>
    <div id="result"></div>
    <script>
        const btn = document.getElementsByTagName('button')[0];

        btn.addEventListener('click', function(){
            const xhr = new XMLHttpRequest();
            //超时设置  如果超时2s就取消
            xhr.timeout = 2000;
            //网络回调
            xhr.ontimeout = function(){
                alert('网络异常,请稍后重试');
            }
            //网络异常回调
            //onerror 错误监视器
            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;
                    }
                }
            }
        })
    </script>

手动取消请求

<button>点击发送</button>
    <button>取消发送</button>

    <script>
        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();
        }
    </script>

nidi.js
定时发送的响应体

const express = require('express');
const app = express();
app.all('/delay', (request, response) => {
   //响应头
    response.setHeader('Access-Control-Allow-Headers','*');
    //延时响应 3s做出响应
    setTimeout(() => {
        //设置响应体
        response.send('延时响应');
    }, 3000);
    
});
app.listen(8000, () => {
    console.log("服务已经启动,8000端口监听中");
});

请求重复发送问题

多次相同请求,只会给服务端发送一个请求

<button>点击发送</button>
    <script>
        const btns = document.querySelectorAll('button');
        let x = null;
        //标识变量
        let nidi = false;//是否在发送AJAX请求

        btns[0].onclick = function(){
            //判断标识变量
            if ( nidi) x.abort();//如果正在发送,则取消该请求,创建一个新的请求
            x = new XMLHttpRequest();
            //修改标识变量值
            nidi = true;
            x.open("GET", 'http://127.0.0.1:8000/delay');
            x.send();
            x.onreadystatechange = function(){
                if(x.readyState === 4){
                    //有可能请求失败,所以不用再做判断,只要拿到结果
                    nidi = false;//拿到服务器的全部结果后,设置false
                }
            }
        }
    </script>

Axios发送AJAX请求

1.安装axios
npm i axios

2.在线引用

可以去BootCND上面找

< script crossorigin=“anonymous” src=“https://cdn.bootcdn.net/ajax/libs/axios/1.3.4/axios.min.js”>

配置服务器

const express = require('express');
const app = express();
//all方式 可以接受任意类型的请求
app.all('/axios-server', (request, response) => {
    //设置响应头    允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');  
   //响应头
    response.setHeader('Access-Control-Allow-Headers','*'); 
        //设置响应体
        const data = {name:'nidi'};
        response.send(JSON.stringify(data)); 
});
app.listen(8000, () => {
    console.log("服务已经启动,8000端口监听中");
});

发送GET请求

const btns = document.querySelectorAll('button');
        btns[0].onclick = function(){
            //GET请求 决定给谁发
            axios.get('http://127.0.0.1:8000/axios-server',{
                //url参数
                params: {
                    id: 100,
                    vip: 7
                },
                headers: {
                    name:'nidi',
                    age:20
                }
            });
        }

tip:可用baseURL对url进行简化

//配置baseURL
axios.defaults.baseURL='http://127.0.0.1:8000';
axios.get('axios-server',{
});

数据返回是基于Promise的:

.then(value => {
                console.log(value);
            })

axios发送请求成功的值是一个封装好的响应对象
我们需要的响应数据藏在response.data

发送POST请求

 btns[1].onclick = function() {
            axios.post('http://127.0.0.1:8000/axios-server', {
                username: 'nidi',
                password: '1234'
            },{
                params: {
                    id:100,
                    vip: 7
                },
                headers: {
                    height: 180,
                    weight: 180,
                }
            });
        }

axios函数发送通用请求

btns[2].onclick = function (){
            axios({
                // 请求方法
                method: 'POST',
                // url
                url: 'http://127.0.0.1:8000/axios-server',
                // url参数
                params: {
                    vip:10,
                    level:30
                },
                // 头信息
                headers: {
                    a:100,
                    b:200
                },
                // 请求体
                data: {
                    username: 'admin',
                    password: 'admin'
                }
            }).then((response) =>{
        console.log(response);//全部响应结果
        console.log('响应状态码:', response.status);
        console.log('响应状态字符串:',response.statusText);
        console.log('响应头信息:', response.headers);
        console.log('响应体:', response.data);
    })

        }

总结
axios本质上是对原声XMLHttpRequest的封装,不需要复杂的步骤

1.创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();

2.初始化,给定请求方式以及请求地址
xhr.open(“请求方式”, ulr地址);

3.发送请求
xhr.send();

4.获取服务器端给客户端的响应数据
现在只需要写axios.get或axios.post或通用请求

feth()函数发送AJAX请求

const btns = document.querySelector('button');
        btns.onclick = function () {
            //参数在
            fetch('http://127.0.0.1:8000/fetch-server?vip=10',{
                //请求方法
                method:'POST',
                //请求头
                headers:{
                    name:'nidi'
                },
                //请求体
                body:'username=nidi&&password=1234'
            }).then(response => {
                return response.text();
       //如果服务端放回结果是json,就把text改为json,会自动解析成json对象
            }).then(response =>{
                console.log(response);
            });
        }        

同源策略

网页ulr和ajax请求的目标资源的url的协议、域名、端口保持一致
违背同源策略就是跨域

//要从http://120.0.0.1:9000/home打开,这样才能做到9000端口同源
<h1>你弟啊</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>

const express = require('express');
const app = express();
app.get('/home', (request, response) => {
   response.sendFile(__dirname + '/nidi.html');
});
app.get('/data', (request, response) => {
    response.send('用户数据');
});
app.listen(9000, () => {
    console.log("服务已经启动,9000端口监听中");
});


解决跨域的方法

JSONP(非官方),只支持get请求
利用script标签的跨域能力来发送请求

CORS(官方),跨域资源贡献
不需要在客户端做任何操作,完成在服务器中进行处理
CORS通过设置一个响应头来告诉浏览器允许跨域

response.setHeader('Access-Control-Allow-Headers','*');

原生jsonp的实践

输入框失去焦点后,input变红,p显示文字

用户名: <input type="text" id="username">
    <p></p>
    <script>
        //获取input元素
        const input = document.querySelector('input');
        const p = document.querySelector('p');
        
        //声明handl函数
        function handle(data){
            input.style.border = "solid 1px #f00";
            //修改p标签的提示文本
            p.innerHTML = data.msg
        }
        
        //绑定事件
        input.onblur = function(){
            //获取用户的输入值
            let username = this.value;
            //向服务端发送请求检查用户名是否存在
            //1.创建script标签
            const script = document.createElement('script');
            //2.设置标签的src属性
            script.src = 'http://127.0.0.1:8000/check-username';
            //3.将script插入到文档中(不插入就无法向服务端发送请求)
            //把script插入到body标签的最后
            document.body.appendChild(script);
        }
    </script>

app.all('/check-username', (request,response) => {
    const data = {
        exist: 1,
        msg:'用户名已经存在'
    };
    //将数据转化为字符串
    let str = JSON.stringify(data);
    //返回结果
    response.end(`handle(${str})`);
});

//还要再开一个8000端口
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值