AJAX(一)

一、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 上,当该对象触发指定的事件时,指定的回调函数就会被执行。事件目标可以是一个文档上的元素 Element、Document 和 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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/286983.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Apache-2.0】springboot-openai-chatgpt超级AI大脑产品架构图

springboot-openai-chatgpt: 一个基于SpringCloud的Chatgpt机器人&#xff0c;已对接GPT-3.5、GPT-4.0、百度文心一言、stable diffusion AI绘图、Midjourney绘图。用户可以在界面上与聊天机器人进行对话&#xff0c;聊天机器人会根据用户的输入自动生成回复。同时也支持画图&a…

解决json.decoder.JSONDecodeError: Extra data: line 1 column 721 (char 720)问题

python中将字符串序反列化成json格式时报错 fn result_json[0].decode(utf-8).strip(\00) json_object json.loads(fn) print(type(json_object))排查了以下原因应该是序列化的字符串全都在一行&#xff0c;json库不能一次性处理这么长的序列

每天刷两道题——第三天

1.1两两交换链表中的节点 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09; 输入&#xff1a;[1,2,3,4] 输出&#xff1a;[2,1,4,3…

摄像头监控系统/视频监控云平台EasyCVR鼠标指示故障,该如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

OLED硬件电路设计

OLED,全称有机自发光二极管。其主要通过控制注入子像素发光材料的电流大小&#xff0c;实现不同颜色的显示。 OLED屏幕的每个像素点都可以理解成一颗独立控制的灯珠&#xff0c;开启时只需要进行显示的像素点即可。不像LCD一样&#xff0c;显示需要整块背光的亮度&#xff0c;…

fastadmin传递参数给html和js,通过身份判断动态显示列表头部住店和离店按钮

首先将管理员或者酒店人员的身份传递给html和js做按钮显示权限 roomorder.php index.html {if $admin_id != 1}<a class="btn btn-success btn-change btn-start btn-disabled" data-params=

2023年总结及2024年目标之关键字“提速”

1. 感受 时光荏苒&#xff0c;都365天下来了&#xff0c;从一开始试水&#xff0c;到后面为素材焦虑&#xff0c;然后有存货了&#xff0c;渐渐也就习惯成自然了&#xff0c;现在回头看&#xff0c;还是那句话"事非经过不知难"&#xff0c;后面再来一句&#xff0c;…

【Linux操作系统】探秘Linux奥秘:进程与任务管理的解密与实战

&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《操作系统实验室》&#x1f516;诗赋清音&#xff1a;柳垂轻絮拂人衣&#xff0c;心随风舞梦飞。 山川湖海皆可涉&#xff0c;勇者征途逐星辉。 目录 &#x1fa90;1 初识Linux OS &…

SpringSecurity-2.7中跨域问题

SpringSecurity-2.7中跨域问题 访问测试 起因 写这篇的起因是会了解到 SSM(CrosOrigin)解决跨域,但是会在加入SpringSecurity配置后,这个跨域解决方案就失效了,而/login这个请求上是无法添加这个注解或者通过配置(WebMvcConfig)去解决跨域,所以只能使用SpringSecurity提供的.c…

Jmeter实现分布式并发

Jmeter实现分布式并发&#xff0c;即使用远程机执行用例。 环境&#xff1a; VMware Fusion Windows系统是win7。 操作过程 1、Master在jmeter.properties添加remote_hosts 2、Slave在jmeter.properties添加server_port 同时把remote_hosts修改为和主机&#xff08;Master…

c++初阶-------类和对象

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

以问答的方式解释编译器与解释器

编译器 编译器是什么&#xff1f; 编译器是一种计算机程序&#xff0c;它可以将源代码转换成目标代码。编译器通常包括一个词法分析器、一个语法分析器和一个代码生成器。 编译器将源代码转换为可执行的目标代码&#xff0c;可以在计算机上运行。编译器通常还负责优化生成的代码…

polar CTF web 被黑掉的站

一、题目 二、解答 1、dirsearch 扫目录 看到shell.php和index.php.bak 一看就是爆破&#xff0c;字典都给了&#xff0c;最后得到为 nikel

【数据结构】二叉搜索(查找/排序)树

一、二叉搜索树基本概念 1、定义 二叉搜索树&#xff0c;又称为二叉排序树&#xff0c;二叉查找树&#xff0c;它满足如下四点性质&#xff1a; 1&#xff09;空树是二叉搜索树&#xff1b; 2&#xff09;若它的左子树不为空&#xff0c;则左子树上所有结点的值均小于它根结…

2023年终总结与展望

2023年终总结 自2019年3月13日入驻CSDN&#xff0c;至今四年零九个月。截至2023年12月31日&#xff0c;CSDN博客已发原创博文120篇&#xff0c;粉丝9822位&#xff0c;访问量超过176万次。 2022年12月31日数据情况&#xff1a; 2023年12月31日数据情况&#xff1a; 从 年终数…

跟着cherno手搓游戏引擎【2】:日志系统spdlog和premake的使用

配置&#xff1a; 日志库文件github&#xff1a; GitHub - gabime/spdlog: Fast C logging library. 新建vendor文件夹 将下载好的spdlog放入 配置YOTOEngine的附加包含目录&#xff1a; 配置Sandbox的附加包含目录&#xff1a; 包装spdlog&#xff1a; 在YOTO文件夹下创建…

再见2023,你好2024(附新年烟花python实现)

亲爱的朋友们&#xff1a; 写点什么呢&#xff0c;我已经停更两个月了。2023年快结束了&#xff0c;时间真的过得好快&#xff0c;总要写点什么留下纪念吧。这一年伴随着许多挑战和机会&#xff0c;给了我无数的成长和体验。坦白说&#xff0c;有时候我觉得自己好像是在时间的…

一起学docker(四)| 数据卷 + 简单应用部署(MySQL,Tomcat,Nginx,Redis)

Docker 容器数据卷 Docker容器产生的数据&#xff0c;如果不备份&#xff0c;那么当容器实例删除后&#xff0c;容器内的数据也就消失了。需要对数据进行持久化。 为了保存docker中的数据&#xff0c;可以使用数据卷。 是什么 卷就是目录或文件&#xff0c;存在于一个或多个…

HUAWEI华为荣耀MagicBook X 15酷睿i5-10210U处理器集显(BBR-WAH9)笔记本电脑原装出厂Windows10系统

链接&#xff1a;https://pan.baidu.com/s/1YVcnOP5YKfFOoLt0z706rg?pwdfwp0 提取码&#xff1a;fwp0 MagicBook荣耀原厂Win10系统自带所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办公软件、华为/荣耀电脑管家等预装程序 文件格式&#xff1a;esd/wim/swm 安装…

深度学习|10.5 卷积步长 10.6 三维卷积

文章目录 10.5 卷积步长10. 6 三维卷积![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b5bfa24f57964b0f81f9602f5780c278.png) 10.5 卷积步长 卷积步长是指每计算一次卷积&#xff0c;卷积移动的距离。 设步长为k&#xff0c;原矩阵规模为nxn&#xff0c;核矩阵…