AJAX学习笔记

1.预备部分:Express的安装

Express框架:
我们通过ajax需要对服务端发对请求,所以我们需要这个服务端接收和发送
1.初始化node.js

npm init --yes

2.安装express
  在项目文件夹下安装express框架(而不是整个全局环境)

npm i express

3.创建项目文件夹,并加入服务端代码server.js

4.启动服务,在终端中执行
  注意得是在代码所在的上一级文件夹的终端上进行运行。例如文件路径为express/server.js,则终端需要运行在express下,否则无法执行。

node server.js

5.防止更改服务端代码时每次都要重新运行的操作
  nodemon是一种工具,可以自动检测到目录中的文件更改时通过重新启动应用程序来调试基于node.js的应用程序。开发过程中使用nodemon来替代node进行运行服务端代码,每次修改服务端代码的时候不需要重新run一遍,而是会自动重启并且自动更新内容。
  首先需要安装nodemon,-g代表进行全局安装的意思。全局安装完成之后其他文件下也能使用nodemon。

npm install -g nodemon

MacOS安装方法:
  需要在安装指令前面加上sudo,然后输入密码进行安装。

sudo npm install nodemon -g --registry=https://registry.npm.taobao.org

安装完后使用 nodemon来运行服务端代码

nodemon server.js

2. AJAX的简单理解

(1)解释

  AJAX = 异步 JavaScript 和 XML。AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。AJAX实现的主要效果是局部刷新,即在页面不刷新(不更换的情况下填充新的内容,一般是从服务器中获取数据,利用JS代码这些数据进行处理封装成新的内容来补充到网页上去)。

(2)页面刷新

  一般认为点击页面的刷新按钮是进行页面刷新,或者是切换新的页面(网页URL发生改变)也叫做页面刷新。

3. AJAX的基本操作和方法

(1)GET请求和请求参数设置

代码get.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>Document</title>
    <style>
        #result {
            height: 200px;
            width: 200px;
            border: 1px solid blue;
        }
    </style>
</head>

<body>
    <button>点击发送请求</button>
    <div id="result">

    </div>
    <script>
        //通过tag标签来获取到对象   但由于通过标签只能获取到对象集合  因此还需要加上一个下标
        var btn = document.getElementsByTagName("button")[0];
        var res = document.getElementById("result");

        //绑定btn按下事件
        btn.onclick = function () {
            //1.创建请求对象
            const xhr = new XMLHttpRequest();
            //2.初始化 设置请求方法和URL
            xhr.open('GET', "http://127.0.0.1:8000/server?a=100&b=200&c=300");
            //3.进行发送(向服务器端)
            xhr.send();
            //4.进行事件绑定 处理服务器端返回的结果
            //onreadystatechang代表每次状态值的改变会触发function函数
            //on 当……的时候
            //readystate是xhr对象中的属性,有5个状态值:0 1 2 3 4;
            //0是初始化状态,最初该值就为0;状态1表示open方法调用完毕;状态2表示send方法调用完毕;状态3表示服务端返回了部分结果;状态4表示服务端返回了所有结果
            //change代表  改变   进行状态改变时才会触发
            xhr.onreadystatechange = function () {
                //判断服务端是否返回了所有结果
                if (xhr.readyState === 4) {
                    //响应报文中的状态码status只要为2XX就代表响应成功
                    if (xhr.status >= 200 && xhr.status < 300) {     //判断响应状态是否成功(要是响应不成功 返回的结果内容也不是正确的)
                        //处理结果  行 头 空行 体
                        console.log(xhr.status);    //状态码
                        console.log(xhr.statusText);    //状态字符串
                        console.log(xhr.getAllResponseHeaders);     //头
                        console.log(xhr.response);

                        res.innerHTML = xhr.response;
                    } else {
                        console.log("服务器返回不成功");
                    }
                }
            }
        }
    </script>
</body>

</html>

模拟服务端:server.js

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

//2.创建应用对象(引用这个express) 
//进行一个服务器的模拟  监听端口发来的请求根据请求的内容 并进行相应的效果响应
const app=express();

//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/server',(request,response)=>{
    //设置响应头,代表允许跨域(即在不同域名之间进行数据交换)
    response.setHeader('Access-Control-Allow-origin','*');
    //设置响应体
    response.send("HELLO AJAX!");
});


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


效果展示:
在这里插入图片描述
再进行get请求操作的时候,只需要在URL地址后面加上问号和对应的参数与值,其中使用&作为分隔符。

(2)POST请求和请求头设置、请求体设置

<!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 {
            height: 200px;
            width: 200px;
            border: 1px solid blue;
        }
    </style>
</head>

<body>
    <div id="result">

    </div>
    <script>
        var res = document.getElementById("result");

        //给div区域绑定时间(鼠标悬停事件响应)
        res.addEventListener('mouseover', function () {
            //1.创建请求对象
            const xhr = new XMLHttpRequest();
            //2.初始化 设置请求方法和URL
            xhr.open('POST', "http://127.0.0.1:8000/server");
            //3.进行发送(向服务器端):发送请求体一般存在两种发送方式
            //请求体内容是通过send方式发送到服务端的
            xhr.send('a=100&b=200&c=300');
            // xhr.send('a:100&b:200&c:300');       //发送josn格式

            //4.进行事件绑定 处理服务器端返回的结果
            xhr.onreadystatechange = function () {
                //判断服务端是否返回了所有结果
                if (xhr.readyState === 4) {
                    //响应报文中的状态码status只要为2XX就代表响应成功
                    if (xhr.status >= 200 && xhr.status < 300) {
                        res.innerHTML = xhr.response;
                    } else {
                        console.log("服务器返回不成功");
                    }
                }
            }
        });
    </script>
</body>
</html>
//1.引入express
const express =require('express');

//2.创建应用对象(引用这个express) 
//进行一个服务器的模拟  监听端口发来的请求根据请求的内容 并进行相应的效果响应
const app=express();

//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装

//设置post请求方式支持
app.post('/server',(request,response)=>{
    //设置响应头,代表允许跨域(即在不同域名之间进行数据交换)
    response.setHeader('Access-Control-Allow-origin','*');
    //设置响应体
    response.send("HELLO AJAX! POST");
});

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

效果展示:
在这里插入图片描述

(3)AJAX自定义请求头

  在AJAX中的请求头一般都是预定义的,这样便能被服务器所识别,但是同样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>AJAX之POST请求</title>
    <style>
        #result {
            height: 200px;
            width: 200px;
            border: 1px solid blue;
        }
    </style>
</head>

<body>
    <div id="result">

    </div>
    <script>
        var res = document.getElementById("result");

        res.addEventListener('mouseover', function () {
            const xhr = new XMLHttpRequest();
            xhr.open('POST', "http://127.0.0.1:8000/server");

            //设置预定义的请求头  这是代表设置请求体内容的类型 
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            //设置自定义的请求头(按照名字,值的格式进行设置)
            xhr.setRequestHeader('name', 'value');

            xhr.send('a=100&b=200&c=300');
            // xhr.send('a:100&b:200&c:300');       //发送josn格式

            //4.进行事件绑定 处理服务器端返回的结果
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        res.innerHTML = xhr.response;
                    } else {
                        console.log("服务器返回不成功");
                    }
                }
            }
        });
    </script>
</body>
</html>
//1.引入express
const express =require('express');

//2.创建应用对象(引用这个express) 
//进行一个服务器的模拟  监听端口发来的请求根据请求的内容 并进行相应的效果响应
const app=express();

//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装

//设置all的方式 代表支持所有的请求(包括get请求、post请求或者其他请求)
app.all('/server',(request,response)=>{
    //设置响应头,代表允许跨域(即在不同域名之间进行数据交换)
    response.setHeader('Access-Control-Allow-origin','*');

    //响应头(加上后能支持自定义响应头) 星号代表支持所有的类型
    response.setHeader('Access-Control-Allow-Headers','*');

    //返回响应体
    response.send("HELLO AJAX! POST");
});


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

在这里插入图片描述

(4)服务端响应json格式

  在AJAX服务端中无法直接向前端发送json格式的数据,response.send()所发送出来的都是字符串格式的数据,而无法直接发送发一个json格式的对象。因此在向前端发送json格式的数据时,首先会进行一个字符串化的操作:JSON.stringify()。
  而在前端接收到字符串格式的json数据时,我们在AJAX中一般有两种方式将字符串格式的数据还原为json格式的数据:

(1)手动方式
(2)自动方式——利用XMLHttpRequest对象的自带的属性responseType

前端接收服务端json格式数据显示效果:
  只是以字符串的形式展现出来,而我们实际上想要获得的是json格式的object对象
在这里插入图片描述
手动方式:
前端关键代码:

		// var res = document.getElementById("result");
        var res = document.querySelector("#result");    //通过ID选择器名称来确定对象

        //绑定键盘事件
        window.onkeydown = function () {        //只要有键盘按下 则会触发事件
            const xhr = new XMLHttpRequest();
            xhr.open('GET', "http://127.0.0.1:8000/json");
            xhr.send();
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {//响应成功
                        let data = JSON.parse(xhr.response);//手动格式转换
                        console.log(data);          //控制台输出的不再是字串 而是一个object对象
                        res.innerHTML = data.name + " " + data.age;
                    }
                }
            }
        }

服务器端关键代码:

app.get('/json',(request,response)=>{
    //设置响应头,代表允许跨域(即在不同域名之间进行数据交换)
    response.setHeader('Access-Control-Allow-origin','*');
    //响应头(加上后能支持自定义响应头) 星号代表支持所有的类型
    response.setHeader('Access-Control-Allow-Headers','*');
    let content={
        name:"cr7",
        age:"36"
    };      //  构建一个json格式的数据变量

    let str=JSON.stringify(content);        //字符串格式化
    //返回响应体
    response.send(str);
});

在这里插入图片描述
自动方式:
前端关键代码:

		// var res = document.getElementById("result");
        var res = document.querySelector("#result");    //通过ID选择器名称来确定对象
        //绑定键盘事件
        window.onkeydown = function () {        //只要有键盘按下 则会触发事件
            const xhr = new XMLHttpRequest();
            
            xhr.responseType = "json";          //设置返回的响应体的数据格式为json格式(这是json格式的自动转换)
            
            xhr.open('GET', "http://127.0.0.1:8000/json");
            xhr.send();
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {//响应成功
                        console.log(xhr.response);  //  此时的response已经是一个object对象了
                        res.innerHTML = xhr.response.name + " " + xhr.response.age;
                    }
                }
            }
        }

服务器端关键代码:
  与手动方式相同
在这里插入图片描述

(5)IE缓存问题解决

  在其他类型的浏览器例如chrome或者safari之类的浏览器一般不存在缓存问题,即服务器数据发生改变后会及时传回前端,导致前端的显示数据也发生改变。但是IE浏览器存在一个缓存机制,导致前端的数据更新比较慢,因此要在IE浏览器上进行前端显示时,我们可以使用以下方法来解决IE浏览器的缓存问题:
原有代码:

xhr.open('GET', "http://127.0.0.1:8000/ie");

修改后获取实时数据:
  使得IE浏览器在服务端数据更改时,会发送新的数据请求,而不是走本地缓存。

xhr.open('GET', "http://127.0.0.1:8000/ie?t="+Datanow());

(6)请求超时、网络异常处理

<!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 {
            height: 200px;
            width: 200px;
            border: 1px solid blue;
        }
    </style>
</head>

<body>
    <button>点击发送请求</button>
    <div id="result">

    </div>
    <script>
        //通过tag标签来获取到对象   但由于通过标签只能获取到对象集合  因此还需要加上一个下标
        var btn = document.getElementsByTagName("button")[0];
        var res = document.getElementById("result");

        btn.onclick = function () {
            const xhr = new XMLHttpRequest();

            //超时设置 2s
            xhr.timeout = 2000;       //timeout
            //超时回调——即超时显示的内容
            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) {
                        res.innerHTML = xhr.response;
                    } else {
                        console.log("服务器返回不成功");
                    }
                }
            }
        }
    </script>
</body>
</html>
//1.引入express
const express =require('express');

//2.创建应用对象(引用这个express) 
//进行一个服务器的模拟  监听端口发来的请求根据请求的内容 并进行相应的效果响应
const app=express();

//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/delay',(request,response)=>{
    //设置响应头,代表允许跨域(即在不同域名之间进行数据交换)
    response.setHeader('Access-Control-Allow-origin','*');
    
    //设置响应   延迟发送
    setTimeout(()=>{
        response.send("延迟响应");
    },3000);
});

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

在这里插入图片描述

(7)取消请求和重复请求发送问题

  取消请求一般调用AJAX对象中的abort方法来进行取消请求

//进行请求
xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8000/delay');
xhr.send();
//取消上述请求
xhr.abort();

下面实现一个解决重复发送请求问题:
  也就是当发送一个新的请求时,如果之前还有相同的请求没有发送完成,那就取消之前的未完成的相同请求,而只发送当前的新请求。这样一来会极大地缓解服务端的访问压力。
案例:

<!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>
    <button>发送请求</button>
    <button>取消请求</button>
    <script>
        var btn = document.querySelectorAll("button");        //获取一个对象集合
        let isSending = false;   //保存是否正在发送请求的变量

        let xhr = null;
        btn[0].onclick = function () {
            if (isSending) xhr.abort();     //取消之前所正在发送的请求,将会创建一个新的请求
            xhr = new XMLHttpRequest();
            isSending = true;
            xhr.open('GET', 'http://127.0.0.1:8000/delay');
            xhr.send();
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    isSending = false;      //当变化状态达到4之后代表发送完成(而不管响应是否成功)
                }
            }
        }

        btn[1].onclick = function () {
            xhr.abort();
        }
    </script>
</body>

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

//2.创建应用对象(引用这个express) 
//进行一个服务器的模拟  监听端口发来的请求根据请求的内容 并进行相应的效果响应
const app=express();

//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/delay',(request,response)=>{
    //设置响应头,代表允许跨域(即在不同域名之间进行数据交换)
    response.setHeader('Access-Control-Allow-origin','*');
    
    //设置响应   延迟发送
    setTimeout(()=>{
        response.send("延迟响应");
    },3000);
});

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

在这里插入图片描述

多次按下请求键,导致正在发送的请求被取消,而创建一个新的发送请求

(8)通过jQuery发送AJAX请求

  通过jQuery的方式进行AJAX请求的时候,使用GET方法和POST方法是类似的,而且所调用的方法中的参数也一致。而使用jQuery方法进行AJAX的通用型请求时,所使用的方法则和GET和POST方法不同。

使用方法如下所示:

$.get()
$.post()
$.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>jQuery发送AJAX请求</title>

    <!-- 新 Bootstrap 核心 CSS 文件 -->

    <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->

    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>

    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->

    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <!-- 引用bootstrap的CDN框架 -->
</head>

<body>
    <div class="container">
        <!-- 下面的class方法都是来源于上面的bootstrap.min.css -->
        <h2 class="page-header">jQuer发送AJAX请求的3种常见方式</h2>
        <button class="btn btn-primary">GET方式</button>
        <button class="btn btn-danger">POST方式</button>
        <button class="btn btn-info">AJAX通用型方式</button>
    </div>

    <script>
        $("button").eq(0).click(function () {
            //在js中的json格式数据中,值为数字的时候可以加上引号也可以不加  效果是一样的
            $.get('http://127.0.0.1:8000/jquery-server', { name: 12, pwd: 'admin' }, function (data) {
                console.log(data);
                //此处的回调function函数的参数是http报文的响应体内容
            }, 'json');
            //直接使用get方法  第一个参数为URL地址,第二个为json格式的URL参数,第三个为回调函数,第四个代表返回的数据为json格式进行自动识别
        });

        $("button").eq(1).click(function () {
            $.post('http://127.0.0.1:8000/jquery-server', { name: "admin", pwd: "admin" }, function (data) {
                console.log(data);
                //此处的回掉函数的参数是http报文的响应体内容
            });
            //直接使用post方法  第一个参数为URL地址,第二个为json格式的URL参数,第三个为回调函数
        });

        $("button").eq(2).click(function () {
            //ajax方法的参数是一个对象(json格式)
            $.ajax({
                //URL
                url: 'http://127.0.0.1:8000/jquery-server',
                //参数
                data: { name: 12, pwd: 43 },
                //请求类型(支持多种请求方式)
                type: 'GET',
                //响应体的类型  如果不写json格式则会默认为字符串格式
                dataType: 'json',
                //成功的回调
                success: function (data) {
                    console.log(data);
                },
                //超时时间设置  超过了则请求失败
                timeout: 2000,
                //请求失败时候的回调结果
                error: function () {
                    console.log('出错啦!!');
                },
                //请求头的信息(此处可以自定义)
                headers: {
                    aa: 100,
                    b: 200
                }

            });
        });
    </script>
</body>

</html>

服务端

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

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

//3.创建路由规则
//使用all方法支持所有的请求方式
app.all('/jquery-server',(request,response)=>{
    response.setHeader('Access-Control-Allow-origin','*');
    response.setHeader('Access-Control-Allow-Headers','*');
    // response.send("HELLO jQuery AJAX!");
    const temp={
        name:'xxx'
    };
    response.send(JSON.stringify(temp));
    //将json格式数据字符串化才能发送
});

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


在这里插入图片描述
更多参数信息可参考:
https://jquery.cuishifeng.cn/jQuery.Ajax.html
https://jquery.cuishifeng.cn/jQuery.get.html
https://jquery.cuishifeng.cn/jQuery.post.html

(9)Axios发送AJAX请求

  Axios是Vue中经常使用的发送AJAX请求的技术。

  • axios.post
    使用axios.post发送AJAX请求时:第一个参数时基础地址加在后面的后缀地址,第二个参数是请求体,第三个参数是其他配置,而第三个参数或者第二个参数后面可以使用箭头函数来对返回的value进行操作。

  • axios.get
    使用axios.get发送AJAX请求时:和post方法类似,但是由于get方法 没有请求体,因此第二个参数为其他配置,并且URL参数直接在其他配置中设置params即可。

  • axios通用方式
    使用axios通用方式的时候只有一个参数对象,请求体的信息全部写入其中,格式非常规范。

  • axios回调函数
    axios中的回调函数存在两个,一个是function(response)另一个是functuon(error)。响应成功时调用function(response),当响应失败的时候才会调用function(error)。在使用时用如下形式即可:

    .then(function(response){},function(error){});
    或者
    .then(response=>{},error=>{});
    

案例:

<!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>axios发送AJAX请求</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.js"></script>
    <!-- 通过CDN方式引入axios工具 -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> -->

</head>

<body>
    <h2>axios发送AJAX请求</h2>
    <hr>
    <button>GET</button>
    <button>POST</button>
    <button>AJAX通用方式</button>

    <script>
        //通过dom操作获取对象集合
        const btn = document.getElementsByTagName('button');

        //设置baseURL  注意defaults不要写成default
        axios.defaults.baseURL = 'http://127.0.0.1:8000';

        btn[0].onclick = function () {
            //get请求  注意get方式不存在请求体  该内容被URL参数所取代
            axios.get('/axios-server', {
                //此处方针一些请求体数据信息
                //URL参数
                params: {
                    a: 100,
                    b: 100
                },
                //请求头信息
                headers: {
                    name: 'xxx',
                    value: 'yyy'
                }
            }).then(value => {
                //类似于回调函数  响应体的信息   可以在这里进行返回数据的处理操作
                console.log(value);
            });
        }

        btn[1].onclick = function () {
            //post请求  第二个参数为请求体信息
            axios.post('/axios-server?a=345', {
                username: 'admin',
                password: 'admin'
            }, {
                //此处方针一些请求体数据信息
                //请求头信息
                headers: {
                    name: 'xxx',
                    value: 'yyy'
                }
            }).then(value => {
                //类似于回调函数  响应体的信息   可以在这里进行返回数据的处理操作
                console.log(value);
            });
        }

        btn[2].onclick = function () {
            //axios通用方式发送AJAX请求
            axios({
                //设置请求方式
                methos: 'post',

                url: '/axios-server',

                //URL参数
                params: {
                    a: 100,
                    b: 100
                },
                //请求头信息
                headers: {
                    name: 'xxx',
                    value: 'yyy'
                },
                //data中存放请求体信息
                data: {
                    username: 'admin',
                    password: 'admin'
                }
            }).then(response => {
                //响应状态码
                console.log(response.status);
                console.log(response.status);
                //响应状态字符串
                console.log(response.statusText);
                //响应头
                console.log(response.headers);
                //响应体
                console.log(response.data);

            });
        }
    </script>
</body>

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

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

//3.创建路由规则
//使用all方法支持所有的请求方式
app.all('/axios-server',(request,response)=>{
    response.setHeader('Access-Control-Allow-origin','*');
    response.setHeader('Access-Control-Allow-Headers','*');
    // response.send("HELLO Axios AJAX!");
    const temp={
        name:'xxx'
    };
    response.send(JSON.stringify(temp));
    //将json格式数据字符串化才能发送
});



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

在这里插入图片描述

(10)通过fetch函数发送AJAX请求

  fetch()方法提供了一种简单、合理的方式来跨网络异步获取资源。

fetch(url,请求体对象)
.then(function(response){return response.json()})
.then(function(myJson){console.log(myJson)});

案例:

<!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>fetch发送AJAX请求</title>
</head>

<body>
    <button>AJAX 请求</button>

    <script>
        const btn = document.querySelector('button');

        btn.onclick = function () {
            //fetch函数的第一个参数是URL地址,第二个参数是一个对象(包含请求的一些基本信息 以json格式储存),URL的参数直接缀在URL地址中
            fetch('http://127.0.0.1:8000/fetch-server?vip=777', {
                //请求方法
                method: 'POST',
                //请求头信息
                headers: {
                    header: 'hhh',
                    tail: 'ttt'
                },
                //请求体(此处的字符串貌似不需要加引号)
                body: 'name=admin&age=12',
            }).then(response => {
                return response.json();
                //将返回结果解析为json对象
                //注意点:通过return返回响应体内容时   后面还需跟着一个then打印response
            }).then(response => {
                console.log(response);
                //  打印响应体的信息  这是一个对象  包含了响应体的行 头 和体信息
            });
        }
    </script>

</body>

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

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

//3.创建路由规则
//使用all方法支持所有的请求方式
app.all('/fetch-server',(request,response)=>{
    response.setHeader('Access-Control-Allow-origin','*');
    response.setHeader('Access-Control-Allow-Headers','*');
    // response.send("HELLO jQuery AJAX!");
    const temp={
        name:'cr7',
        id:'goat'
    };
    response.send(JSON.stringify(temp));
    //将json格式数据字符串化才能发送
});

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

在这里插入图片描述
其他详细参考资料:
https://developer.mozilla.org/zh-CN/docs/Web/API/fetch
https://www.cnblogs.com/baron-li/p/13170001.html

(11)AJAX同源解释

  同源网页资源代表来自同一个源点,指的是协议、域名、端口号完全相同,违背同源策略即是跨域。而AJAX是默认遵守同源策略的,

下面一个同源的案例:
  启动服务端,在浏览器中输入http的URL地址,直接显示了html前端界面,该前端界面来自于http://127.0.0.1:9000而不是来自于本地的硬盘,而服务端的来源也是http://127.0.0.1:9000,因此我们认为这是同源的。

<!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 同源策略</title>
</head>

<body>
    <h1>同源测试</h1>
    <hr size="3px ">
    <button>获取服务端用户数据</button>

    <script>
        const btn = document.querySelector('button');

        btn.onclick = function () {
            var xhr = new XMLHttpRequest();
            //痛通过http的URL访问前端页面时  由于此处的前端和后端资源都来自于同一个端口  满足同源颜策略  因此前端访问后端数据的时候不在需要具体的URL地址
            //因此此处的路径简写为/data  因为程序会自动补全对应的http的URL地址
            xhr.open('GET', '/data');
            xhr.send();
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        console.log(xhr.response);
                        //此处的response直接是响应体内容了
                    }
                }
            }

        }
    </script>
</body>

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

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

//3.创建路由规则
//使用all方法支持所有的请求方式
app.all('/home',(request,response)=>{
    //注意此处未设置跨域头  因为本身就会满足同源策略
    response.sendFile(__dirname+'/tong.html');
    //当访问这个URL地址的时候  返回(发送)的是一个文件  该文件是从服务端同个地方获取的
});

app.get('/data',(request,response)=>{
    response.send('用户数据');
});

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

在这里插入图片描述
  此处的前端页面和用户数据都来源于同一个服务器,都来源于一个端口号,不需要在服务端设置跨域头信息即已经满足同源策略。

  而在本地通过live server插件打开前端页面则会产生跨域问题,如下所示,无法获取到/data的数据,因为该数据在本地硬盘中是不存在的。
在这里插入图片描述

(12)JSONP解决同源跨域问题

在这里插入图片描述

演示举例:
此处通过http请求方式引入了js代码,说明script标签支持跨域访问。

<!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>
    <style>
        #result {
            width: 300px;
            height: 400px;
            border: 3px solid black;
            text-align: center;
            line-height: 400px;
            font-size: 15px;
            color: bule;
            margin: 100px auto;
        }
    </style>
</head>

<body>
    <div id='result'>

    </div>

    <script>
        //定义一个处理数据的函数
        function handle(data) {
            const dd = document.getElementById('result');
            dd.innerHTML = data.name + " " + data.age;
        }
    </script>

    <!-- <script src='./serverdata.js'></script> -->
    <!-- 上面的方式是本地内嵌JS文件         而下面的方法是通过http请求获取的  来源不同 -->
    <script src='http://127.0.0.1:5500/JSONP/serverdata.js'></script>
</body>

</html>
const data={
    name:'xxx',
    age:100
}

console.log(data);

//正式调用函数(调用一定得在定义之后)
handle(data);

在这里插入图片描述
在这里插入图片描述

从本地启动前端界面:

<!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>
    <style>
        #result {
            width: 300px;
            height: 400px;
            border: 3px solid black;
            text-align: center;
            line-height: 400px;
            font-size: 15px;
            color: bule;
            margin: 100px auto;
        }
    </style>
</head>

<body>
    <div id='result'>

    </div>

    <script>
        //定义一个处理数据的函数
        function handle(data) {
            const dd = document.getElementById('result');
            dd.innerHTML = data.name + " " + data.age;
        }
    </script>

    <script src='http:/127.0.0.1:9000/jsonp-server'></script>

</body>

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

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

//3.创建路由规则

app.all('/jsonp-server',(request,response)=>{
    //向客户端发送的是字符串  但是这个字符串实际上是JS代码
    // response.send('console.log("hello JSONP")');
    const data={
        name:'JSONP',
        age:100
    }
    let str=JSON.stringify(data);
    //返回结果  此处返回的是JS代码中的一个函数调用
    response.end(`handle(${str})`);
    //此处只是为了方便字符串的拼接使用了模版字符串${}
});

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

在这里插入图片描述

通过上面的方式进行跨域时,由于是通过script方式实现跨域访问的,因此在进行服务端的内容返回时不应该单纯地只回传数据,而应该回传的是相应的JS代码。

模版字符串参考资料:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Template_literals

(13)jQuery发送jsonp请求

注意callback参数在jquery发送jsonp中的使用
  这个参数可以起名为callback,也可以叫其他的名字,但是必须以类似的形式缀在URL地址的末尾,否则返回跨域错误,即无法实现跨域。但是通过这个参数的作用,便解决了跨域问题,响应体的内容也是基于这个参数返回的。可以把这个参数当作载体从前端传给服务端,服务端获取到这个载体后,将响应体放在这个载体中回传给客户端,解决了跨域问题。

<!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>jQuery-JSONP</title>
    <style>
        #result {
            width: 400px;
            height: 300px;
            border: 1px solid blueviolet;
        }
    </style>
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
</head>

<body>
    <button>发送jsonp请求</button>
    <div id="result">

    </div>
    <script>
        //用jquery方式获取操作对象
        $("button").eq(0).click(function () {
            //下面的URL地址后面 必须跟上一个固定的参数 callback=?
            $.getJSON('http://127.0.0.1:9000/jquery-jsonp?callback=?', function (data) {
                // console.log(data);
                $('#result').html(
                    `名称:${data.name}
                    <br>
                    年龄:${data.age}`
                )
            });
        });
    </script>
</body>

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

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

//3.创建路由规则

app.all('/jquery-jsonp',(request,response)=>{
    //向客户端发送的是字符串  但是这个字符串实际上是JS代码
    // response.send('console.log("hello JSONP")');

    const data={
        name:'JSONP',
        age:100
    }

    let str=JSON.stringify(data);
    //返回结果  此处返回的是JS代码中的一个函数调用

    //接收callback参数
    let cb=request.query.callback;

    response.end(`${cb}(${str})`);
    //此处只是为了方便字符串的拼接使用了模版字符串${}
});

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


在这里插入图片描述

(14)CORS解决跨域问题

  CORS是官方给出的一种解决跨域的方法,操作方法非常简单,只需要在服务端设置响应头即可:

//设置响应头,代表允许跨域(即在不同域名之间进行数据交换)
response.setHeader('Access-Control-Allow-origin','*');
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值