【尚硅谷】3小时Ajax入门到精通_精华笔记

文章目录


前言

AJAX是学习Promise和Axios的前置知识。


一、课程说明

1.AJAX是什么?

Ajax的全称是“Asynchronous JavaScript and XML”,即“异步JavaScript和XML”,它允许Web应用程序在不重新加载整个页面,也可以在不刷新的情况下,通过在后台与服务器进行数据交换来更新部分网页。Ajax的核心对象是XMLHttpRequest,它使得浏览器能够发出HTTP请求并接收HTTP响应,同时浏览器可以继续进行其他操作,当收到服务器的响应后,浏览器再更新相应的页面部分。Ajax技术可以使Web应用程序更加快速、响应更加灵敏,并且提供更好的用户体验,Ajax的优点包括减少带宽使用、提高应用程序的响应速度以及维护数据的局部更新。许多现代Web应用程序,如Google Maps、Gmail等,都广泛使用了Ajax技术。

2.AJAX简介

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

二、AJAX网页应用

如下图所示:如果不把鼠标放在京东的家用电器这个一级分类上,它的二级分类就不会被请求,也就不会被展示。实现了一个懒加载的效果,用则加载,不用则不加载。或者看今日头条新闻时,不忘下滚动页面,下面的页面是不加载的,只有滚动到下面时才会加载,再展示出来,且不用刷新,这都依赖于AJAX。
在这里插入图片描述

三、XML简介

XML(Extensible Markup Language)名叫可扩展标记语言。
XML被设计用来传输和存储数据。HTML用来呈现数据
XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据。
比如说我有一个学生数据:name=“孙悟空”;age=18;gender=“男”;
用XML表示:

<student>
 <name>孙悟空</name>
 <age>18</age>
 <gender></gender>
 </student>

现在已经被JSON取代了。用JSON表示:{"name":"孙悟空","age":18,"gender":"男"}

四、AJAX的优缺点

1. AJAX 的优点

  1. 可以无需刷新页面而与服务器端进行通信。
  2. 允许你根据用户事件(特定行为,比如把鼠标放在一级分类上)来更新部分页面内容。

2. AJAX 的缺点

  1. 没有浏览历史,不能回退
  2. 存在跨域问题(同源),a.com的网页向b.com的网页发送请求是不允许的。
  3. SEO不友好,爬虫爬不到动态创建的数据。

五、HTTP协议请求报文与响应文本结构

AJAX发的请求就是HTTP请求,把协议搞懂后,就可以在协议这个层面,搞懂数据交换的流程。AJAX发送方式有四种:原生、jQuery、fetch、axios。

HTTP是什么

HTTP(hypertext transport protoco1)协议,超文本传输协议,协议详细规定了浏览器和万维网服务器之间互相通信的规则。

1、HTTP规定了请求,请求报文

请求报文格式(四部分)
请求行:分为三部分:请求类型(GET、POST等)、URL路径或者查询字符串、HTTP协议版本
请求头:Host、Cookie、Cotent-type等。
空行:固定的必须要有
请求体:如果是GET请求,请求体为空,如果是POST请求,请求体可以不为空。
在这里插入图片描述

2、HTTP规定了响应,响应报文

行: 协议版本、相应状态码、响应状态字符串
头:Content-Type、Content-encoding等
空行:必须有
体:主要的返回结果比如 <html> <head> </head> <body> <h1>尚硅谷</h1> <body> <html>页面进行渲染和呈现
在这里插入图片描述

六、Chrom控制台查看网络通信报文

1.请求在哪看

在这里插入图片描述
如下图所示,第一个红框为请求方式,第二个为url,第三个为HTTP协议版本,下面的为请求头的参数,格式为一个头加冒号加内容。
在这里插入图片描述
如下图所示其中,Payload中显示请求体。
在这里插入图片描述

note:

1、请求路径中的请求参数(两种传参方式)
1.1请求查询参数(Query Parameters)(URL问号后面的参数)
http://example.com/api?param1=value1&param2=value2
1.2请求路径参数(URI)(URL路径中的参数)
http://example.com/api/param1/param2

这些参数一般用于查询字符串,适用于传递非敏感的、长度较短的信息。
优点
简单,容易构造和解析。
对于简单的、无状态的请求很方便。
缺点
会暴露在浏览器历史记录、服务器日志、网络抓包工具等多个地方,不适合传输敏感信息。
长度有限制,不同浏览器和服务器对URL长度有不同的限制。
不适用于传输大量数据。

2、请求体中的参数

这种方式通常用于POST、PUT等请求,用于上传较大或结构化的数据,例如JSON、XML或表单数据。
优点
可以传输大量数据。
可以传输复杂的数据结构,例如嵌套的JSON对象。
更适合传输敏感或私密信息。
缺点
通常需要指定Content-Type来描述数据类型。
相对更消耗带宽。

2.响应在哪看

在这里插入图片描述
其中响应体会在Response中。如下图所示
在这里插入图片描述

七、NodeJS的安装与介绍

版本:v14.5.0
介绍:Node可以解析JS代码对计算机资源进行操控。
我们AJAX运行过程中需要一个服务端,所以需要NodeJS。

八、Express框架介绍与基本使用

介绍:

我们AJAX需要给服务端发请求,所以需要一个服务端,这里选择Express。这里只需使用Express的基本功能
我们先用VS打开项目文件夹(自己现在建一个),然后打开终端执行npm i express。然后编写名为 express基本使用.js 代码如下

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

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

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

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

然后执行这个代码,执行代码的代码为node express基本使用.js ,如下面两图所示,说明启动express服务成功。
在这里插入图片描述
在这里插入图片描述

查看请求头,响应头,响应体

下面对之前学过的请求头,响应头,响应体进行查看,之后自己有需要查看的可以自行查看,从此处开始查看不再赘述。
在这里插入图片描述

在这里插入图片描述

九、AJAX案例准备

我们的需求:准备一个button按钮,点击后向服务端发送请求,把服务端的响应的结果呈现出来。

前端页面的准备

<!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>
    <style>
        #result{
            width:200px;
            height:100px;
            border:solid 1px #90b;
        }
    </style>
</head>
<body>
    <button>点击发送请求</button>
    <div id="result"></div>
</body>
</html>

效果如下图所示
在这里插入图片描述

服务端的准备 server.js

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

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

//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/server', (request, response) => {
    //设置响应头  "*"实现设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    //设置响应体
    response.send('HELLO AJAX');
});

效果如以下两图所示:
在这里插入图片描述
在这里插入图片描述

十、AJAX请求的基本操作

改进前端页面
note:控制台Network中选中XHR是对AJAX请求的一个筛选。
在这里插入图片描述

<!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>
    <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/server');
            //3. 发送
            xhr.send();
            //4. 事件绑定 处理服务端返回的结果
            // on  when 当....时候
            // readystate 是 xhr 对象中的属性, 表示状态 0 1 2 3 4
            //XHR对象的readyState属性对应有五个值,它们的含义如下:
  			//0:未初始化。尚未调用open()方法
			//1:启动。已经调用open()方法,但是还没有调用send()方法
			//2:发送。已经调用send()方法,但是还没有接收响应
			//3:接收。已经接收到部分数据
			//4:完成。已经接收到全部响应数据,并且可以在客户端使用了
            // change  改变
            xhr.onreadystatechange = function(){
                //判断 (readyState是4说明服务端返回了所有的结果)
                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设置请求参数

之前我们都是在地址栏传参。
AJAX中操作方式一样,在URL后面缀参数。在1-GET.html中更改一下。

xhr.open('GET', 'http://127.0.0.1:8000/server');//替换成下面
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');

如下图所示,则参数发送成功,之后查看参数都是在这里查看不再赘述。
在这里插入图片描述

十二、AJAX发送POST请求

需求:把鼠标放在div上面发POST请求,然后把响应体信息显示到div中。
前端内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AJAX POST 请求</title>
    <style>
        #result{
            width:200px;
            height:100px;
            border:solid 1px #903;
        }
    </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();
            //4. 事件绑定
            xhr.onreadystatechange = function(){
                //判断
                if(xhr.readyState === 4){
                    if(xhr.status >= 200 && xhr.status < 300){
                        //处理服务端返回的结果
                        result.innerHTML = xhr.response;
                    }
                }
            }
        });
    </script>
</body>
</html>

server.js中加入下面代码并重新启动服务

//可以POST类型的请求 
app.post('/server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    //响应头
    response.setHeader('Access-Control-Allow-Headers', '*');
    //设置响应体
    response.send('HELLO AJAX POST');
});

十三、AJAX POST设置请求体

修改前端html内容如下:

//3. 发送
xhr.send();//改为下面一种格式
xhr.send('a=100&b=200&c=300');
xhr.send('a:100&b:200&c:300');
xhr.send('1233211234567');

十四、AJAX POST设置请求头信息

只需要在open()方法后面加一个调用即可。

//设置请求头
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('name','atguigu');

在server.js中我们把app.post()改为app.all()

//可以接收任意类型的请求 
app.all('/server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    //响应头
    response.setHeader('Access-Control-Allow-Headers', '*');
    //设置响应体
    response.send('HELLO AJAX POST');
});

十五、服务端响应JSON数据

需求:键盘按下,就会发送请求,然后响应体结果在div中呈现。
前端代码:对json数据有两种转换方式,第二种比较方便。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JSON响应</title>
    <style>
        #result{
            width:200px;
            height:100px;
            border:solid 1px #89b;
        }
    </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/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;
                        // 1. 手动对数据转化
                        // let data = JSON.parse(xhr.response);
                        // console.log(data);
                        // result.innerHTML = data.name;
                        // 2. 自动转换
                        console.log(xhr.response);
                        result.innerHTML = xhr.response.name;
                    }
                }
            }
        }
    </script>
</body>
</html>

server.js中添加如下代码:

//JSON 响应
app.all('/json-server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    //响应头
    response.setHeader('Access-Control-Allow-Headers', '*');
    //响应一个数据
    const data = {
        name: 'atguigu'
    };
    //对对象进行字符串转换
    let str = JSON.stringify(data);
    //设置响应体
    response.send(str);
});

十六、nodemon自动重启工具安装

Nodemon是一个帮助开发基于node.js的应用程序的工具,当检测到目录中的文件更改时,它会自动重启node应用程序。

npm install -g nodemon //安装再通过下面命令重启server.js
nodemon server.js

十七、IE缓存问题(chrom不存在此问题)

IE缓存问题是什么?
AJAX请求发送后,返回的数据会被存储到IE浏览器缓存,那AJAX再发送请求,显示的数据是之前的旧数据,而不是从服务器得到的最新数据。
前端代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IE缓存问题</title>
    <style>
        #result{
            width:200px;
            height:100px;
            border:solid 1px #258;
        }
    </style>
</head>
<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?t='+Date.now());
            xhr.send();
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){
                    if(xhr.status >= 200 && xhr.status< 300){
                        result.innerHTML = xhr.response;
                    }
                }
            }
        })
    </script>
</body>
</html>

服务端添加代码如下:

//针对 IE 缓存
app.get('/ie', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    //设置响应体
    response.send('HELLO IE - 5');
});

十八、超时与网络异常

当发生超时或者网络异常时,对用户进行提醒。前端的timeout时间大于后端的延时时间,则不会触发"网络异常, 请稍后重试!!“,会正常收到响应体。小于则会触发"网络异常, 请稍后重试!!”。
前端代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>请求超时与网络异常</title>
    <style>
        #result{
            width:200px;
            height:100px;
            border:solid 1px #90b;
        }
    </style>
</head>
<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();
            //超时设置 2s 设置
            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;
                    }
                }
            }
        })
    </script>
</body>
</html>

server.js代码添加如下代码:

app.all('/delay', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    setTimeout(() => {
        //设置响应体
        response.send('延时响应');
    }, 1000)
});

通过选择箭头右边的倒三角选择Offline模式来测试“你的网络似乎出了一些问题!"功能。
在这里插入图片描述

十九、AJAX取消请求

在结果还没回来,超时时间也还没到的时候,自己(在后端延时时间到达前)取消请求。
前端代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>取消请求</title>
</head>
<body>
    <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>
</body>
</html>

效果如下图所示:
在这里插入图片描述

二十、AJAX请求重复发送问题

如果用户得不到想要的结果对一个按钮疯狂点击,那会发送很多相同请求,那服务器会接收很多相同请求,服务器的压力比较大。
前端代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>重复请求问题</title>
</head>
<body>
    <button>点击发送</button>
    <script>
        //获取元素对象
        const btns = document.querySelectorAll('button');
        let x = null;
        //标识变量
        let isSending = false; // 是否正在发送AJAX请求

        btns[0].onclick = function(){
            //判断标识变量
            if(isSending) x.abort();// 如果正在发送, 则取消该请求, 创建一个新的请求
            x = new XMLHttpRequest();
            //修改 标识变量的值
            isSending = true;
            x.open("GET",'http://127.0.0.1:8000/delay');
            x.send();
            x.onreadystatechange = function(){
                if(x.readyState === 4){
                    //修改标识变量
                    isSending = false;
                }
            }
        }

        // abort
        btns[1].onclick = function(){
            x.abort();
        }
    </script>
</body>
</html>

二十一、jQuery发送AJAX请求

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jQuery 发送 AJAX 请求</title>
    <link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
    <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>
        $('button').eq(0).click(function(){
       		//第一个参数是url,第二个参数是参数,第三个参数是回调,其参数是响应体,可以对响应体(参数)进行一些操作
            $.get('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
                console.log(data);//对响应体(参数)进行一些操作,加了下一行的json参数,console输出的是一个对象。
            },'json');//这个json参数,表示响应体是json格式。
        });

        $('button').eq(1).click(function(){
            $.post('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
                console.log(data);//不加下一行的json参数,console输出的是一个字符串。
            });
        });
		//通用方法如下
        $('button').eq(2).click(function(){
            $.ajax({
                //url
                url: 'http://127.0.0.1:8000/jquery-server',
                //参数
                data: {a:100, b:200},
                //请求类型
                type: 'GET',
                //响应体结果
                dataType: 'json',//console输出结果为对象。
                //成功的回调
                success: function(data){
                    console.log(data);
                },
                //超时时间
                timeout: 2000,
                //失败的回调
                error: function(){
                    console.log('出错啦!!');
                },
                //头信息
                headers: {
                    c:300,
                    d:400
                }
            });
        });

    </script>
</body>
</html>

server.js添加以下内容:

//jQuery 服务
app.all('/jquery-server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    // response.send('Hello jQuery AJAX');
    const data = {name:'尚硅谷'};
    response.send(JSON.stringify(data));
});

二十二、Axios发送AJAX请求

Axios是前端最热门的AJAX的工具库,使用频率高,也是vue和react推荐的工具包。
前端代码如下:

<!DOCTYPE html>
<html lang="en">
//crossorigin="anonymous"实现跨域,因为后面的地址与本文件地址不在同一个域中
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>axios 发送 AJAX请求</title>
    <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.js"></script>
</head>

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

    <script>
        // https://github.com/axios/axios
        const btns = document.querySelectorAll('button');

        //配置 baseURL
        axios.defaults.baseURL = 'http://127.0.0.1:8000';

        btns[0].onclick = function () {
            //GET 请求
            axios.get('/axios-server', {
                //url 参数
                params: {
                    id: 100,
                    vip: 7
                },
                //请求头信息
                headers: {
                    name: 'atguigu',
                    age: 20
                }
            }).then(value => {
                console.log(value);
            });
        }

        btns[1].onclick = function () {
            axios.post('/axios-server', {//第二个参数是请求体
                username: 'admin',
                password: 'admin'
            }, {
                //url 
                params: {
                    id: 200,
                    vip: 9
                },
                //请求头参数
                headers: {
                    height: 180,
                    weight: 180,
                }
            });
        }
    	//Axios的通用方法
        btns[2].onclick = function(){
            axios({
                //请求方法
                method : 'POST',
                //url
                url: '/axios-server',
                //url参数
                params: {
                    vip:10,
                    level:30
                },
                //头信息
                headers: {
                    a:100,
                    b:200
                },
                //请求体参数
                data: {
                    username: 'admin',
                    password: 'admin'
                }
            }).then(response=>{
                //响应状态码
                console.log(response.status);
                //响应状态字符串
                console.log(response.statusText);
                //响应头信息
                console.log(response.headers);
                //响应体
                console.log(response.data);
            })
        }
    </script>
</body>
</html>

server.js添加如下代码:

//axios 服务
app.all('/axios-server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    // response.send('Hello jQuery AJAX');
    const data = {name:'尚硅谷'};
    response.send(JSON.stringify(data));
});

二十三、fetch函数发送AJAX请求

前端代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>fetch 发送 AJAX请求</title>
</head>
<body>
    <button>AJAX请求</button>
    <script>
        //文档地址
        //https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch
        
        const btn = document.querySelector('button');
        btn.onclick = function(){
            fetch('http://127.0.0.1:8000/fetch-server?vip=10', {
                //请求方法
                method: 'POST',
                //请求头
                headers: {
                    name:'atguigu'
                },
                //请求体
                body: 'username=admin&password=admin'
            }).then(response => {//fetch返回的是个promise对象,用then回调来处理结果
                // return response.text();
                return response.json();//这个方法是定义好的
            }).then(response=>{
                console.log(response);
            });
        }
    </script>
</body>
</html>

下图为在上面代码中第一个then中直接console.log(response),即可查看到定义好的text()方法,之后直接进行了调用。
在这里插入图片描述
server.js添加代码如下:

//fetch 服务
app.all('/fetch-server', (request, response) => {
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Headers', '*');
    // response.send('Hello jQuery AJAX');
    const data = {name:'尚硅谷'};
    response.send(JSON.stringify(data));
});

二十四、同源策略

同源策略(Same-OriginPolicy) 最早由 Netscape 公司提出,是浏览器的一种安全策略。当前的网页的url和AJAX请求的目标的url,他俩的协议、域名、端口号 必须完全相同,才是满足同源的。
同源: 协议、域名、端口号 必须完全相同。
违背同源策略就是跨域。
示例:
前端代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>首页</title>
</head>
<body>
    <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>
</body>
</html>

我们重新一个server.js,代码如下:

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("服务已经启动...");
});

如下图所示,我们通过在浏览器中输入http://127.0.0.1:9000/home,首先从协议为http,url为127.0.0.1,端口为9000处获得了home这个网页,然后再通过点击“点击获取用户数据”来向同源的“/data”发送请求,所以没有跨域问题。我们之前的代码没有跨域问题是因为加了响应头,设置了允许跨域。
在这里插入图片描述

二十五、如何解决跨域问题,jsonp的实现原理

1.JSONP 是什么

JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get请求。

2.JSONP 怎么工作的?

在网页有一些标签天生具有跨域能力,比如:img、link、iframe、script。JSONP 就是利用script 标签的跨域能力来发送请求的。

3.示例如下:

前端代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>原理演示</title>
    <style>
        #result {
            width: 300px;
            height: 100px;
            border: solid 1px #78a;
        }
    </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/jsonp-server"></script>
</body>
</html>

后端server.js添加代码如下:(注意:此处没有添加跨域头)

//jsonp服务
app.all('/jsonp-server',(request, response) => {
    // response.send('console.log("hello jsonp")');
    const data = {
        name: '尚硅谷atguigu'
    };
    //将数据转化为字符串
    let str = JSON.stringify(data);
    //返回结果的形式为一个函数调用,这个函数(此函数需要在客户端声明,不然报错)的参数就是我们想给客户端的结果数据
    response.end(`handle(${str})`);
});

二十六、jQuery发送jsonp请求

前端代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jQuery-jsonp</title>
    <style>
        #result{
            width:300px;
            height:100px;
            border:solid 1px #089;
        }
    </style>
    <script crossorigin="anonymous" src='https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js'></script>
</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){//callback=?是固定格式
                $('#result').html(`
                    名称: ${data.name}<br>
                    校区: ${data.city}
                `)
            });
        });
    </script>
</body>
</html>

如下图所示,我们可以看出虽然上面callback=?我们没写值,但发送请求时候是带值的。说明前端已经注册了这个函数,之后服务器端返回这个函数的调用,前端就可以对数据进行处理。
在这里插入图片描述
在这里插入图片描述

server.js添加代码如下:

app.all('/jquery-jsonp-server',(request, response) => {
    // response.send('console.log("hello jsonp")');
    const data = {
        name:'尚硅谷',
        city: ['北京','上海','深圳']
    };
    //将数据转化为字符串
    let str = JSON.stringify(data);
    //接收 callback 参数
    let cb = request.query.callback;

    //返回结果 带上callback参数 固定格式
    response.end(`${cb}(${str})`);
});

二十七、CORS响应头–跨域请求另外一种解决方案

跨源资源共享(CORS)官网

1. CORS是什么?

CORS(Cross-OriginResourceSharing),跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。

2.CORS怎么工作的?

CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。

3.CORS的使用

主要是服务器端的设置:

router.get("/testAJAX",function(req,res){
	//通过res 来设置响应头,来允许跨域请求
	//res.set("Access-Control-Allow-Origin","http://127.0.0.1:3000");
 	res.set("Access-Control-Allow-Origin","*");
 	res.send("testAJAX 返回的响应");
 })

总结

AJAX的基本概念与使用。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值