AJAX(一)

发布时间:2024年01月03日

一、AJAX简介


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

页面出现新内容但是页面没有进行刷新即为异步。
四种方式发送ajax:原生、jQuery、fetch、axios

AJAX的示例如下所示:

1.

其中输入abcd而引起的相关的关键字并不是本地生成的,而是通过向服务器发送请求,数据从服务器返回回来的。

2.

注册的时候报错的提醒即为AJAX,将注册账号发送给服务器,服务器进行校验,然后返回对应结果。不可用即出现该提醒。

3.

?按需加载,利用率提升,页面的加载速度变快。

4.

?出现二级三级菜单,也是AJAX的体现,鼠标放上去之后才会向服务器发送请求,服务器响应后,然后返回结果。

5.

当滚动条滚到底以后,会向服务器发送AJAX请求,从服务器返回新的数据。通过js将数据做一个处理,在页面当中动态创建新的节点,将整个内容做一个填充。

1.XML的认识和初识JSON:?

XML:可扩展标记语言
XML被设计用来传输和存储数据(通过网络以XML的形式返给客户端,客户端就可以使用)而HTML在网页当中呈现数据。
XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据。

比如说有一个学生数据:

name="孙悟空“;age=18;gender="男”;

用XML表示:

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

最开始AJAX在进行数据交换的时候所使用的格式就是XML,服务器端给客户端浏览器返回结果时返回的就是XML格式的一个字符串,前端js在接到这个结果以后,对这个内容做一个解析。把数据提取出来,对数据做一个处理。现在已经被JSON取代。比起XML,JSON更加简洁,在数据转换也更加容易。可以直接借助JSON的一些API的方法,快速将字符串转成js对象。灵活度远胜于XML
{"name":"孙悟空”,"age":18,"gender":"男"}

2.AJAX的优缺点:

AJAX的优点:
可以无需刷新页面而与服务器端进行通信
允许你根据用户事件来更新部分页面内容。
AJAX的缺点:
没有浏览历史,不能回退
存在跨域问题(不可以向a.com向b.com发送AJAX请求)
SEO(搜索引擎优化)不友好,网页中的内容爬虫是爬取不到的。

我们在源码里面进行搜索的时候:

发现里面并没有。?因为这些内容都是通过AJAX异步请求的方式来得到的结果。

源代码结果里面是没有商品信息的,源代码是响应体(HTTP响应的一部分)。

通过AJAX向服务端发送请求,服务端返还结果,然后通过js动态的创建到页面当中去的。爬虫的话爬不到商品的数据。

3.HTTP协议:

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

协议就是一种约定,规则。

我按一种规则发送请求,你按一种规则返回结果。

(1)请求报文

重点是格式与参数

请求行 :请求类型(GET、POST、DELETE、PUT)/URL的路径? HTTP的版本/1.1

请求头:

Host: rgf.com

Cookie: name=woer

Content-type: application/x-www-form-urlencoded(告诉服务器请求体是什么类型)

User-Agent: chrome 83

名字+:+空格+值

请求空行

请求体(GET请求:请求体是空的,POST请求:请求体可以不为空。)

完整的HTTP请求报文:username=admin&password=admin

(2)响应报文

响应行:协议版本? HTTP/1.1? ? 响应状态码? 200? 响应状态字符串? OK

响应头:

Content-Type:text/html;charset=utf-8

Content-length:2048

Content-encoding:gzip

响应空行

响应体(主要的返回结果):

<html>
? ?<head>
? ? ?</head>
? ? ? ? ?<body>
? ? ? ? ?<h1>响应体</h1>
? ? ? ? </body>
</html>

在向服务端发送请求的时候,服务端给浏览器返回的结果包括这四部分,而html内容在响应体这块,浏览器在接到结果之后,会把响应体结果提取出来,对内容做一个解析,在页面做一个渲染和显示。

(3) GET请求演示:

请求行和请求头信息:?

对URL参数做一个解析之后的结果:(请求参数)

?可以看到参数有没有发送过去。

即可查看HTTP协议版本:

响应行和响应头信息:?

响应体信息:

preview是一个预览 ,对响应体解析之后的查看界面:

?(4)POST请求:

?原始的请求体的内容:

表单点击提交按钮之后,浏览器会帮助我们去把HTTP的报文给封装好,封装好后发送到目标服务器的指定端口,去做一个请求。?

4.node.js和?Express服务端框架::

node.js可以用来解析js代码,通过js代码对计算机资源做一个操作。ajax应用当中需要一个服务端。

下载 | Node.js 中文网 (nodejs.cn)

安装成功。

我们进行检测是否安装成功:

node.js安装成功。

(1) Express服务端框架:

Express - 基于 Node.js 平台的 web 应用开发框架 - Express中文文档 | Express中文网 (expressjs.com.cn)

AJAX需要给服务端发送请求,需要一个服务端。

Express,基于Node.js平台,快速、开放、极简的Web开发框架。

npm是一个包管理工具,是node.js平台下的一个包管理工具

npm init --yes,该命令进行一个初始化。

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')
});
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

在命令行中输入node?文件名,即可启动服务器:

我们进入如下网站:

?向8000端口发送请求:

??向8000端口响应请求:响应行和响应头

?响应体:

?在node终端,ctrl+c可以关闭端口。结束服务。

5.ajax案例准备:

GET.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <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>

meta标签详解:HTML <meta> 标签 (w3school.com.cn)?

border的属性及写法:

属性含义
solid实线
dotted点线
dashed虚线
double双线

service.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')

});
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

初识const:

const定义的变量不可以修改,而且必须初始化。?

var定义的变量可以修改,如果不初始化会输出undefined,不会报错。

let是块级作用域,函数内部使用let定义后,对函数外部无影响。

运行之后如下所示:

当我们点击按钮的时候,向服务端发送请求,服务端返回响应体结果,在div中做一个呈现。页面不刷新。?

此时启动成功:

我们输入网址查看响应的内容:?

此时响应成功。?

?AJAX请求的基本操作:

我们将GET.html修改为如下所示:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <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];
        //绑定事件
        btn.onclick=function(){
            //
            console.log('test');
        }
       </script>
    </body>
</html>

Document.getElementsByTagName():

返回一个包括所有给定标签名称的元素的 HTML 集合HTMLCollection。整个文件结构都会被搜索,包括根节点。返回的?HTML集合是动态的,意味着它可以自动更新自己来保持和 DOM 树的同步而不用再次调用?document.getElementsByTagName()

Document.getElementsByTagName() - Web API 接口参考 | MDN (mozilla.org)

var elements = document.getElementsByTagName(name);
  • elements?是一个由发现的元素出现在树中的顺序构成的动态的 HTML 集合?HTMLCollection
  • name?是一个代表元素的名称的字符串。特殊字符 "*" 代表了所有元素。

我们进行验证如下:?

对ajax请求做一个筛选。XHR.

GET.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <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];
        //绑定事件
        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(open方法已经调用完毕),2(send方法已经调用完毕),3(服务端返回了部分结果),4(服务端返回了所有结果)
            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);//响应体
               }else{

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

onreadystatechange 事件:

当请求被发送到服务器时,我们需要执行一些基于响应的任务。

每当 readyState 改变时,就会触发onreadystatechange事件。

readyState 属性存有 XMLHttpRequest 的状态信息。

下面是 XMLHttpRequest 对象的三个重要的属性:

属性描述
onreadystatechange存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。
readyState

存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。

  • 0: 请求未初始化
  • 1: 服务器连接已建立
  • 2: 请求已接收
  • 3: 请求处理中
  • 4: 请求已完成,且响应已就绪
status200: "OK"
404: 未找到页面

在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。

运行之后:?

请求信息:?

?

?

?响应体的结果在div做一个呈现:

GET.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <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.事件绑定 处理返回端返回的结果
            //readystate是xhr对象中的属性,表示状态 ,这个属性有五个值:0(未初始化),1(open方法已经调用完毕),2(send方法已经调用完毕),3(服务端返回了部分结果),4(服务端返回了所有结果)
            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;
               }else{

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

Document:getElementById() 方法

Document:getElementById() 方法 - 6Web API 接口参考 | MDN (mozilla.org)

Document?接口的?getElementById()?方法返回一个表示?id?属性与指定字符串相匹配的元素的?Element?对象。由于元素的 ID 在指定时必须是独一无二的,因此这是快速访问特定元素的有效方法。

?

6.AJAX设置请求参数:

一般是在地址栏里面进行传参

?我们在AJAX里面是在里面写如下参数:

?AJAX发布POST请求:

<!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(){
                console.log("test");
            });
        </script>
    </body>
</html>

EventTarget.addEventListener()

EventTarget.addEventListener()?方法将指定的监听器注册到?EventTarget?上,当该对象触发指定的事件时,指定的回调函数就会被执行。事件目标可以是一个文档上的元素?ElementDocument?和?Window,也可以是任何支持事件的对象(比如?XMLHttpRequest)。

备注:?推荐使用?addEventListener()?来注册一个事件监听器,理由如下:

  • 它允许为一个事件添加多个监听器。特别是对库、JavaScript 模块和其他需要兼容第三方库/插件的代码来说,这一功能很有用。
  • 相比于?onXYZ?属性绑定来说,它提供了一种更精细的手段来控制?listener?的触发阶段。(即可以选择捕获或者冒泡)。
  • 它对任何事件都有效,而不仅仅是 HTML 或 SVG 元素。

addEventListener()?的工作原理是将实现?EventListener?的函数或对象添加到调用它的?EventTarget?上的指定事件类型的事件侦听器列表中。如果要绑定的函数或对象已经被添加到列表中,该函数或对象不会被再次添加。

EventTarget.addEventListener() - Web API 接口参考 | MDN (mozilla.org)

测试成功:

<!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>

?运行报错,因为服务端并没有一个与之匹配的路由规则。而且没有设置POST的响应头。当前响应头为GET。匹配不上。

?我们修改如下,之后重新在终端打开运行service.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')

});

app.post('/server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  //设置响应体
  response.send('HELLO AJAX POST')
  
  });
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

先在终端终止服务(ctrl+c),然后在运行(node service.js):

?

?响应行、响应头:

响应体:

?设置请求体:

<!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('a=100&b=200&c=300');
                //4.事件绑定
                xhr.onreadystatechange=function(){
                    //判断
                    if(xhr.readyState==4){
                        if(xhr.status>=200 && xhr.status<300){
                            //处理服务端返回的结果
                            result.innerHTML=xhr.response;
                        }
                    }
                }
            });
        </script>
    </body>
</html>

此种发送数据的格式比较常见:(json的格式也比较多一点)

 xhr.send('a=100&b=200&c=300');

已经传递给服务器:?

?也可以采用:

 xhr.send('a:100&b:200&c:300');

?也可以如下方式:

 xhr.send('1233211456');

7.AJAX设置请求头信息:

GET.html

<!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');
                //设置请求头(头的名字,头的值)Content-Type用来设置请求体内容的类型的
                //application/x-www-form-urlencoded为所发送的参数a=100&b=200&c=300的类型
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                //3.发送
                xhr.send('a=100&b=200&c=300');
                //4.事件绑定
                xhr.onreadystatechange=function(){
                    //判断
                    if(xhr.readyState==4){
                        if(xhr.status>=200 && xhr.status<300){
                            //处理服务端返回的结果
                            result.innerHTML=xhr.response;
                        }
                    }
                }
            });
        </script>
    </body>
</html>

<!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');
                //设置请求头(头的名字,头的值)Content-Type用来设置请求体内容的类型的
                //application/x-www-form-urlencoded为所发送的参数a=100&b=200&c=300的类型
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.setRequestHeader('name','woer');
                //3.发送
                xhr.send('a=100&b=200&c=300');
                //4.事件绑定
                xhr.onreadystatechange=function(){
                    //判断
                    if(xhr.readyState==4){
                        if(xhr.status>=200 && xhr.status<300){
                            //处理服务端返回的结果
                            result.innerHTML=xhr.response;
                        }
                    }
                }
            });
        </script>
    </body>
</html>

此时会报错,因为我们在请求报文当中添加了一些自定义的请求头,不是预定义的头,而是自定义的头。自定义的这块,浏览器会有安全机制。也可以加自定义,但是需要加一个特殊的响应头。

service.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')
});
//可以接收任意类型的请求
app.post('/server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  //响应头
   response.setHeader('Access-Control-Allow-Headers','*');
  //设置响应体
  response.send('HELLO AJAX POST')
  
  });
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

?此时依然不可以:

发送OPTIONS请求的话,会做一个全新的校验。即发一个请求,看这个头信息可用不可用。

因为这个请求没有得到对应的结果,前端就不能去发这个POST请求,此时可以把post改为all.\

all可以接受任意类型的请求。

//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')
});
//可以接收任意类型的请求
app.all('/server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  //响应头
   response.setHeader('Access-Control-Allow-Headers','*');
  //设置响应体
  response.send('HELLO AJAX POST')
  
  });
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

?此时都有了:

?一般会把身份校验的信息放在头信息里面,把他传递给服务器,由服务器对参数做提取,对用户的一个身份做校验。

8.服务端响应JSON数据:

我们向服务端发送请求,服务端返回结果绝大多数都是JSON格式的数据。

GET.html:

<!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>
            //绑定键盘按下事件
            window.onkeydown=function(){
                console.log('test');
            }
        </script>
    </body>
</html>

onkeydown

在用户按下一个按键时执行Javascript代码:

<input type="text" οnkeydοwn="myFunction()"

定义和用法

onkeydown 事件会在用户按下一个键盘按键时发生。

提示:?与 onkeydown 事件相关联的事件触发次序:

  1. onkeydown
  2. onkeypress
  3. onkeyup

?onkeydown 事件 | 菜鸟教程 (runoob.com)

?我们进行测试:

//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')
});
//可以接收任意类型的请求
app.all('/server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  //响应头
   response.setHeader('Access-Control-Allow-Headers','*');
  //设置响应体
  response.send('HELLO AJAX POST')
  
  });
  app.all('/json-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
     response.setHeader('Access-Control-Allow-Headers','*');
    //设置响应体
    response.send('HELLO AJAX JSON')
    
    });
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

app.listen([port[, host[, backlog]]][, callback])

绑定并监听指定主机和端口上的连接。此方法与 Node 的?http.Server.listen()?相同。

?app.listen([port[, host[, backlog]]][, callback]) - Express 中文文档 (nodejs.cn)

html进行修改:

<!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.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;
                    }
                }
              }
            }
        </script>
    </body>
</html>

我们将响应的改为一个数据:

//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')
});
//可以接收任意类型的请求
app.all('/server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  //响应头
   response.setHeader('Access-Control-Allow-Headers','*');
  //设置响应体
  response.send('HELLO AJAX POST')
  
  });
  app.all('/json-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
     response.setHeader('Access-Control-Allow-Headers','*');
     //响应一个数据
     const data={
      name:'woer'
     }
     //对对象进行字符串转换
     let str=JSON.stringify(data);
    //设置响应体,send方法里面只能接收字符串和Buffer
    response.send(str);
    });
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

JSON.stringify()

JSON.stringify()?方法将一个 JavaScript 对象或值转换为 JSON 字符串,如果指定了一个 replacer 函数,则可以选择性地替换值,或者指定的 replacer 是数组,则可选择性地仅包含数组指定的属性。

JSON.stringify(value[, replacer [, space]])

value:将要序列化成 一个 JSON 字符串的值。

replacer(可选):如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。

space(可选):指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为 10。该值若小于 1,则意味着没有空格;如果该参数为字符串(当字符串长度超过 10 个字母,取其前 10 个字母),该字符串将被作为空格;如果该参数没有提供(或者为 null),将没有空格。

JSON.stringify() - JavaScript | MDN (mozilla.org)

重新运行:

也可以手动通过前台页面进行转换:

<!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.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){
                        // 手动对数据转化
                        let data=JSON.parse(xhr.response);
                        console.log(data);
                        result.innerHTML=data.name;
                        // console.log(xhr.response);
                        // result.innerHTML=xhr.response;
                    }
                }
              }
            }
        </script>
    </body>
</html>

JSON.parse?

JSON.parse()?方法用来解析 JSON 字符串,构造由字符串描述的 JavaScript 值或对象。提供可选的?reviver?函数用以在返回之前对所得到的对象执行变换 (操作)。

语法:

text

要被解析成 JavaScript 值的字符串,关于 JSON 的语法格式,请参考:JSON

reviver?可选

转换器,如果传入该参数 (函数),可以用来修改解析生成的原始值,调用时机在 parse 函数返回之前。

也可以自动通过前台进行数据转换:

<!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){
                        // 手动对数据转化
                        // let data=JSON.parse(xhr.response);
                        // console.log(data);
                        // result.innerHTML=data.name;
                         console.log(xhr.response);
                         //自动转换
                         result.innerHTML=xhr.response.name;
                    }
                }
              }
            }
        </script>
    </body>
</html>

此时设置了数据类型之后,前台能收到的响应数据都是JSON。

9.nodemon:

nodemon - npm (npmjs.com)

帮助我们自动重启服务:

首先我们先暂停服务。

npm install -g nodemon

?我们进行测试:

?当我们修改js之后保存后,服务即会自动重新启动。

10.AJAX请求超时与网络异常处理:(自动取消请求)

(1)请求超时:

GET.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <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();
        //超时设置
        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>

service.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')
});
//延时响应
app.get('/delay',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  setTimeout(()=>{
     //设置响应体
    response.send('延时响应');
  },3000)
  });
//可以接收任意类型的请求
app.all('/server',(request,response)=>{
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin','*');
  //响应头
   response.setHeader('Access-Control-Allow-Headers','*');
  //设置响应体
  response.send('HELLO AJAX POST')
  
  });
  app.all('/json-server',(request,response)=>{
    //设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
     response.setHeader('Access-Control-Allow-Headers','*');
     //响应一个数据
    //  const data={
    //   name:'woer'
    //  }
     //对对象进行字符串转换
    //  let str=JSON.stringify(data);
    //设置响应体,send方法里面只能接收字符串和Buffer
    response.send('HELLO AJAX POST')
    });
/*function chan(){
  return console.log("服务已经启动,8000端口监听中...");
}
可以用如下方法,也可以采用function定义的方法
*/
//4.监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
    })

/*其中
()=>{
console.log("服务已经启动,8000端口监听中...");
}
相当于:
function ajax(){
  return console.log("服务已经启动,8000端口监听中...");
}
*/

超时设置:

网络异常测试:
?

(2) AJAX取消请求:(手动取消)
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <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方法,属于ajax对象的
        btns[1].onclick=function(){
            x.abort();
        } 
       </script>
    </body>
</html>

11.AJAX请求重复发送问题:

GET.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <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方法,属于ajax对象的
        btns[1].onclick=function(){
            x.abort();
        } 
       </script>
    </body>
</html>

XMLHttpRequest.abort()

如果该请求已被发出,XMLHttpRequest.abort()?方法将终止该请求。当一个请求被终止,它的?readyState?将被置为?XMLHttpRequest.UNSENT?(0),并且请求的?status?置为 0。

?XMLHttpRequest.abort() - Web API 接口参考 | MDN (mozilla.org)

文章来源:https://blog.csdn.net/weixin_59448049/article/details/135089898
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。