淘先锋技术网

首页 1 2 3 4 5 6 7

Axios中的AJAX

AXIOS特性

image-20221024163248038

使用CDN链接,在这里不用NPM安装

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>

国内用bootcdn更快

GET请求

		const btn = document.querySelectorAll('button');
        
        //配置base URL
        axios.defaults.baseURL = 'http://127.0.0.1:8000';
        btn[0].onclick = function(){
            //GET请求
            axios.get('/axiosServer',{
                //url参数
                params:{
                    id:114,
                    vip:007
                },
                //请求头信息
                headers:{
                    name:'KUN.A.A',
                    age:'20'
                }
            }).then(value => {
                console.log(value);
            })
        }

image-20221024171403512

js后端

//axios发送
app.all('/axiosServer',(request,response)=>{
	//设置相应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
	//可接受全部响应头
	response.setHeader("Access-Control-Allow-Headers", "*"); 
	const data = {name:'KUN.A.A'}
	// response.send('Hello Jquery AJAX');
	response.send(JSON.stringify(data));
})

后端返回值

image-20221024171431973

可见后端返回值很多,比较完整,同时后端定义的KUN,A,A JSON对象也返回了

POST请求

与GET请求不同,格式稍微有点改变

HTML中的js

 		btn[1].onclick = function(){
            //POST
            axios.post('/axiosServer',
                {//请求体
                    username:'admin',
                    password:'123456'
                },{
                //url参数
                params:{
                    id:514,
                    vip:005
                },
                //请求头信息
                headers:{
                    height:'1990cm',
                    weight:'500kg'
                }
            })
        }

请求体在post函数中的第二个参数,其他参数对象在第三个参数

image-20221024172900934

image-20221024172928219

JS后端与GET相同,不再贴了

axios函数发送请求

个人觉得是最好的方式

        btn[2].onclick = function(){
            axios({
                //请求方法
                method : 'POST',
                //url
                url:'/axiosServer',
                //url参数
                params:{
                    vip:1919,
                    level:810
                },
                //头信息
                headers:{
                    h:150,
                    w:120
                },
                //请求体餐数
                data:{
                    username:'KUN.A.A',
                    password:'1145141919810'
                }
            }).then(Response => {
                //以下代码获取响应体中内容
                //可根据具体要求修改
                console.log(Response);
                //响应状态码
                console.log(Response.status);
                //响应状态字符串
                console.log(Response.statusText);
                //响应头信息
                console.log(Response.headers);
                //响应体
                console.log(Response.data);
            })
        }

完全是一种key - value的形式,只需要按照AXIOS的规则,都可以通过查询官方文档解决

同时JS后端也不变

image-20221024174143620

CONSOL.LOG打印的一串

image-20221024174211102

fetch函数发送AJAX请求

这个函数属于全局函数,可以直接调用

结果是promise对象

改一下后端名字以做区分

//fetch服务
app.all('/fetchServer',(request,response)=>{
	//设置相应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
	//可接受全部响应头
	response.setHeader("Access-Control-Allow-Headers", "*"); 
	const data = {name:'KUN.A.A'}
	// response.send('Hello Jquery AJAX');
	response.send(JSON.stringify(data));
})

前端HTML

	<script>
        const btn = document.querySelector('button');
        btn.onclick = function(){
            fetch('http://127.0.0.1:8000/fetchServer?id=10',{
                //请求方法
                method:'POST',
                //请求头
                headers:{
                    name:'KUN.B.B',
                },
                //请求体
                body:'username=admin&password=admin'
            }).then(response => {
                // console.log(response);
                // return response.text();
                return response.json();
            }).then(response => {
                console.log(response);
            })
        }
    </script>

不同的是需要做两次promise,第一次用对象的函数,第二次才能取到后端返回的值

同时可以直接在URL中写参数

图就不贴了,和前面大同小异

同源策略

浏览器的安全机制

AJAX默认支持同源策略

image-20221024180933241

违背同源策略就是跨域

跨域问题很常见

不是同源策略需要做适配

简单例子,这次端口改成9000,同时也可以复习NODE.JS原生下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>H1H1H1</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>

JS后端

const { request, response } = require('express');
const express = require('express');

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("9000端口已启动");
})

比较简单就不贴图了

这个部分简单介绍了什么是同源并举例,前面的代码大部分是同源只不过学习了不同方法发送AJAX请求与AJAX需要注意的点。

AJAX跨域解决

非官方跨域解决方案

JSONP

只支持GET请求

原生HTML一些标签本来就支持跨域

JSONP就是利用script的跨域能力来发送请求

即是script请求发过去之后,JS后端发回的是JS代码,否则浏览器引擎无法解析

新建一个非同源文件,即跨域,不在同一文件夹下

image-20221024185733463

<!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>
    <style>
        #result{
            width: 400px;
            height: 150px;
            border: solid 1px rgb(255, 0, 0);
        }
    </style>
</head>
<body>
    <div id="result"></div>
    <script>
        //处理数据,自定义函数
        function handle(data){
            //获取result元素
            const result = document.getElementById('result');
            result.innerHTML = data.name;
        }
    </script>
    <script src="http://127.0.0.1:8000/jsonpServer"></script>
</body>
</html>

注意处理数据时候自定义了函数handle

JS后端 继续在8000端口的server中添加

//jsonp服务
app.all('/jsonpServer',(request,response)=>{
	// response.send('consol.log(hello jsonpServer)');
	const data = {
		name:'KUN.C.C'
	};
	//将数据转换为字符串
	let str = JSON.stringify(data);
	//返回结果,返回自定义函数并传参
	response.end(`handle(${str})`);
})

注意end中是键盘左上的``而不是’’

image-20221024185840790

原生JSONP实现

具体做法在代码中比较清楚

HTML

<!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>JSONP案列</title>
</head>
<body>
    用户名:<input type="text" id = "username">
    <p></p>
    <script>
        //获取input元素
        const input =document.querySelector('input');
        const p = document.querySelector('p');
        //声明handle函数
        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插入到文档中
            document.body.appendChild(script);
        }
    </script>
</body>
</html>

JS服务端

//原生JSONP案列
app.all('/check-username',(request,response)=>{
	// response.send('consol.log(hello jsonpServer)');
	const data = {
		exist:1,
		msg:'用户名已存在'
	};
	//将数据转换为字符串
	let str = JSON.stringify(data);
	//返回结果,返回自定义函数并传参
	response.end(`handle(${str})`);
})

image-20221024191734538

Jquery发送JSONP请求

用Jquery发送JSONP的话非常方便

<!DOCTYPE html>
<html >
<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>Jquery发送JSONP AJAX请求</title>
    <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
    <style>
        #result{
            width: 450px;
            height: 180px;
            border: solid 1px #f00;
        }
    </style>
</head>
<body>
    <button>点击发送jsonp请求</button>
    <div id = "result">

    </div>
    <script>
        $('button').eq(0).click(function(){
            $.getJSON('http://127.0.0.1:8000/Jquery-jsonp-server?callback=?',function(data){
                // console.log(data);
                $('#result').html(`
                    名称:${data.name}<br>
                    小区:${data.city}
                `)
            })
        })
    </script>
</body>
</html>

注意Jquery发送JSONP请求时需要加?callback=?参数,以方便服务端回调并显示

JS

//Jquery发送JSONP的AJAX请求
app.all('/Jquery-jsonp-server',(request,response)=>{
	// response.send('consol.log(hello jsonpServer)');
	const data = {
		name:'KUN.A.A',
		city:['北京','上海','武汉']
	};
	//将数据转换为字符串
	let str = JSON.stringify(data);
	//接收callback参数
	let cb = request.query.callback;
	//返回结果,返回自定义函数并传参
	response.end(`${cb}(${str})`);
})

JS服务端需要接收callback参数,并传参,用EI表达式把cb传回,前端

这就是Jquery用JSONP解决跨域问题的方法

image-20221024193724745

设置CORS解决跨域问题的方案

这是解决AJAX跨域另一个方案,并且是官方的跨域解决方案,正规

CORS,跨域资源共享,不需要对客户端做任何操作,完全在服务器中处理,支持GET与POST,跨域通过服务端解决,新增了一组HTTP首部字段

具体首部字段可以看官方文档,同时前面的很多知识点和扩展的官方文档也很完备

最重要的是设置前面一些代码中有的响应头,即可完成跨域请求

//设置响应头
response.setHeader("Access-Control-Allow-Origin",'*')

HTML

<!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>CORS官方跨域请求</title>
    <style>
        #result{
            width: 350px;
            height: 180px;
            border: solid 1px #f00;
        }
    </style>
</head>
<body>
    <button>发送请求</button>
    <div id="result"></div>
    <script>
        const btn = document.querySelector('button');
        btn.onclick = function(){
            //1.创建对象
            const x = new XMLHttpRequest();
            //2.初始化
            x.open("GET","http://127.0.0.1:8000/corsServer");
            //3.发送
            x.send();
            //4.绑定事件
            x.onreadystatechange = function(){
                if(x.readyState === 4){
                    if(x.status >= 200 && x.status < 300){
                        // console.log(x.response);
                        result.innerHTML = x.response;
                    }
                }
            }
        }
    </script>
</body>
</html>
//CORS原生AJAX跨域请求
app.all('/corsServer',(request,response) => {
	//设置响应头
	response.setHeader("Access-Control-Allow-Origin",'*')
	response.send('hello CORS');
})

image-20221024201110743