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.初始化,设置请求方法和urlxhr.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.初始化,设置请求方法和urlxhr.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.初始化  设置类型与URLxhr.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.初始化  设置类型与URLxhr.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.初始化  设置类型与URLxhr.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.初始化  设置类型与URLxhr.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方法里面只能接收字符串和Bufferresponse.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方法里面只能接收字符串和Bufferresponse.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)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信好友添加频繁的原因

01 微信好友添加频繁的原因 1. 添加好友的频率太高&#xff1a;短时间内添加多个好友&#xff0c;系统会认为账号被盗&#xff0c;从而限制用户添加好友&#xff1b; 2. 频繁的发送好友请求&#xff1a;在短时间内连续发送好友请求&#xff0c;也会导致微信限制操作&#xff0…

使用Gitea搭建自己的git远程仓库

Gitea 为什么需要自建仓库 原因只有一个&#xff1a;折腾。其实国内的码云加上github已经足够用了。 官方原话 Gitea 的首要目标是创建一个极易安装&#xff0c;运行非常快速&#xff0c;安装和使用体验良好的自建 Git 服务。我们采用 Go 作为后端语言&#xff0c;这使我们…

com.gexin.platform 依赖下载问题

打包时报错显示&#xff1a; com.gexin.platform:gexin-rp-sdk-http:pom:4.1.1.4 failed to transfer from http://0.0.0.0/ 解决办法&#xff1a; 1、在idea中找到maven中的设置的settings.xml 2、根据路径找到settings.xml文件&#xff0c;添加以下内容 <mirror><…

遇到无序多变请求怎么办,可以试试责任链模式

责任链模式&#xff08;Chain Of Responsibility Design Pattern&#xff09;&#xff0c;也叫做职责链&#xff0c;是将请求的发送和接收解耦&#xff0c;让多个接收对象都有机会处理这个请求。当有请求发生时&#xff0c;可将请求沿着这条链传递&#xff0c;直到有对象处理它…

UDP通信(服务器-客户端)

一、 UDP服务器-客户端通信 UDP&#xff08;User Datagram Protocol&#xff09;是一种面向无连接的传输层协议&#xff0c;它提供了一种简单的、不可靠的数据传输服务。与TCP&#xff08;Transmission Control Protocol&#xff09;不同&#xff0c;UDP不建立连接&#xff0c;…

基于Kettle开发的web版数据集成开源工具(data-integration)-部署篇

目录 &#x1f4da;第一章 前言&#x1f4d7;背景&#x1f4d7;目的&#x1f4d7;总体方向 &#x1f4da;第二章 下载编译&#x1f4d7;下载&#x1f4d7;编译 &#x1f4da;第三章 部署&#x1f4d7;准备工作&#x1f4d5; 安装数据库&redis&consul&#x1f4d5; 修改…

计算机毕业设计-------基于JSP+Servlet的毕业生离校管理系统

需求分析 使用JSPServletMysql技术设计一个毕业生离校管理系统, 整个系统采用BS架构, 为高校方便进行毕业生离校流程进行统一的离校流程, 极大的减少了大量学生同时离校的过程中杂乱的情况, 整个系统分为学生, 教务处, 辅导员, 图书馆, 宿管, 财务处, 系办公室, 管理员登等角色…

【华为机试】2023年真题B卷(python)-考古问题

一、题目 题目描述&#xff1a; 考古问题&#xff0c;假设以前的石碑被打碎成了很多块&#xff0c;每块上面都有一个或若干个字符&#xff0c;请你写个程序来把之前石碑上文字可能的组合全部写出来&#xff0c;按升序进行排列。 二、输入输出 三、示例 示例1: 输入输出示例仅供…

了解Apache 配置与应用

本章内容 理解 Apache 连接保持 掌握 Apache 的访问控制 掌握 Apache 日志管理的方法 Apache HTTP Server 之所以受到众多企业的青睐&#xff0c;得益于其代码开源、跨平台、功能 模块化、可灵活定制等诸多优点&#xff0c;不仅性能稳定&#xff0c;在安全性方面的表现也十分…

【设计模式-2】原型模式的原理、代码实现及类图展示

我们一定对类的实例化比较熟悉&#xff0c;前面我们说的单例、还有3种工厂模式都是通过new关键字来创建对象&#xff0c;下面我们来了解一种新的对象创建的方式。 1. 定义 原型模式也是一种创建型的设计模式&#xff0c;实现和原理总体比较简单&#xff0c;一句话总结呢&#…

Weblogic安全漫谈(二)

前言 继本系列上篇从CVE-2015-4852入手了解T3协议的构造后&#xff0c;本篇继续分析开启T3反序列化魔盒后的修复与绕过。 Weblogic对于10.3.6推出了p20780171和p22248372用于修复CVE-2015-4852&#xff0c;在补丁详情中又提示了p21984589是它的超集&#xff0c;所以可以直接装…

通过软盘拷贝文件 - 华为OD统一考试

OD统一考试(B卷) 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 有一名科学家想要从一台古董电脑中拷贝文件到自己的电脑中加以研究但此电脑除了有一个3.5寸软盘驱动器以外&#xff0c;没有任何手段可以将文件持贝出来&#xff0c;而且只有一张软盘可以…

MySQL将多条数据合并成一条的完整示例

数据库中存的是多条数据&#xff0c;展示的时候需要合并成一条 数据表存储形式如下图 以type分组&#xff0c;type相同的算一条&#xff0c;且保留image和link的所有数据&#xff0c;用groupBy只保留一条数据 解决方案&#xff1a;用GROUP_CONCAT 完整语法如下 group_concat…

从有向带权图判断最短路径里各目标顶点顺序

对如下有向带权图&#xff0c;若采用迪杰斯特拉(Dijkstra)算法求从源点a到其他各顶点的最短路径&#xff0c;则得到的第一路径的目标顶点是b&#xff0c;第二条最短路径的目标顶点是c&#xff0c;后续得到的其余各最短路径的目标顶点依次是() A.d,e,f B.e,d,f C.f,d,e D.f,…

linux-6.0 内核存储栈全景图

linux 存储栈原图地址&#xff1a;https://www.thomas-krenn.com/en/wiki/Linux_Storage_Stack_Diagram

自动驾驶TPM技术杂谈 ———— ODDODC

文章目录 介绍研究现状主流相关定义国标定义SAE定义WP29定义 ODD主流构建框架NHTSA ODD构建框架SAE AVSC ODD构建框架PEGASUS 6层模型BSI ODD构建框架 设计运行条件的原则ODC 的设计原则ODC 元素的制定原则ODC 的使用原则 设计运行条件元素ODD 元素驾乘人员状态4车辆状态 ODC 描…

3分钟Alibaba Cloud Linux镜像操作系统详解

Alibaba Cloud Linux是基于龙蜥社区OpenAnolis龙蜥操作系统Anolis OS的阿里云发行版&#xff0c;针对阿里云服务器ECS做了大量深度优化&#xff0c;Alibaba Cloud Linux由阿里云官方免费提供长期支持和维护LTS&#xff0c;Alibaba Cloud Linux完全兼容CentOS/RHEL生态和操作方式…

深入了解隧道代理HTTP的协议与技术细节

隧道代理HTTP&#xff0c;作为一种网络通信的桥梁技术&#xff0c;其背后的协议与技术细节承载着网络世界的无尽奥秘。对于技术人员而言&#xff0c;深入了解这些细节&#xff0c;不仅有助于优化网络性能&#xff0c;还能为网络安全提供坚实的保障。 一、隧道代理HTTP的协议基…

2024阿里云服务器租赁优惠价格表_ECS和轻量应用服务器配置报价

阿里云服务器租用价格表大全&#xff0c;云服务器一年费用、一个月价格以及1小时收费明细&#xff0c;阿里云2核2G3M带宽轻量服务器一年61元、2核4G4M带宽轻量服务器一年165元12个月&#xff0c;ECS云服务器e系列2核2G配置99元一年、2核4G服务器30元3个月、2核4G配置365元一年、…

二维码、条形码识别

一. 场景介绍 二维码和条形码包含很多信息&#xff0c;对二维码和条形码识别对信息抽取具有重要意义。下面介绍两种二维码识别的方法&#xff0c;并用python实现。 二. 代码实现 import os import cv2 from cv2.wechat_qrcode import WeChatQRCode from pyzbar import pyzba…