一、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: 请求已完成,且响应已就绪
status 200: "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 事件相关联的事件触发次序:
- onkeydown
- onkeypress
- 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)