AJAX(express)
文章目录
- AJAX
- XML 用来传输和保存数据(自定义标签)
- HTTP
- Express
- 请求基本操作
- get请求操作
- POST请求操作
- 设置头信息
- 服务端响应JSON数据
- 网络请求超时及网络异常处理
- 手动取消请求
- 请求重复发送问题
- Axios发送AJAX请求
- feth()函数发送AJAX请求
- 同源策略
- 解决跨域的方法
- 原生jsonp的实践
AJAX
释放端口 ctrl+c
自启动服务端 npx nodemon nidi.js
IE缓存问题解决:添加一个Date.now() 让它知道这是动态
XML 用来传输和保存数据(自定义标签)
目前已经被JSON取代
HTTP
超文本传输协议
HTTP请求报文格式
行 GET/POST /s?ie=utf-t(url) HTTP/1.1(版本)
头 Host: nidi.com
Cookie: name=nidi
Content-type: application/x-www-form-urlencoded
Use-Agent: chrome 83"
空行
体 GET请求体为空,POST请求体可以不为空
响应报文格式
行 HTTP协议版本 响应状态码 响应状态字符串
头
Content-type: text/html;charset=utf/8
Content-length: 2048
Content-encoding: gzip
空行
体 HTML语法内容
<html><head>head><body><h1>h1>body>
html>
Express
//引入express
const express = require('express');
//创建应用对象
const app = express();
//创建路由规则
//request 是请求报文的封装
//response 是对响应报文的封装
app.get('/server', (request, response)=>{
//改成/server,当客户端浏览器发送请求时,url的路径是请求行的第二段的内容他的路径是/server,执行回调函数//设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');//设置响应response.send('hello ajax');
});
//监听端口启动服务
app.listen(8000, ()=>{console.log("服务已经启动,8000端口监听中");
});
释放端口 ctrl+c
请求基本操作
get请求操作
get请求体放在路径后面加?即可
<body><button>点击提示信息</button><div id="result"></div>
</body>
<script>const btn = document.getElementsByTagName('button')[0];btn.onclick = function(){console.log('test');//ajax操作 响应报文//1.创建对象const xhr = new XMLHttpRequest();//2.初始化 设置请求方法和urlxhr.open('GET','http:/127.0.0.1:8000/server?a=100&b=200');//设置请求参数 ?a=100&b=200//3.发生xhr.send();//4.事件绑定//on when当..的时候//redystate 是xhr对象中的属性//状态0 1 2 3 4//0 表示未初始化//1 open方法调用完毕//2 send方法调用完毕//3 服务端返回了部分结果//4 服务端返回了所有结果//change 改变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;}}}}
</script>const express = require('express');
const app = express();
app.get('/server', (request, response) => {//当客户端浏览器发送请求时,url的路径是请求行的第二段的内容他的路径是/server,执行回调函数response.setHeader('Access-Control-Allow-Origin', '*');response.send('hello');
});
app.listen(8000, () => {console.log("服务已经启动,8000端口监听中");
});
POST请求操作
鼠标经过div发送Ajax请求,将请求体显示在div中
post请求体放在send()中
<body><div id="result">放在上面提示信息</div>
</body>
<script>//获取元素对象const result = document.getElementById("result");//绑定事件//mouseover 当鼠标发放在上面时发送请求result.addEventListener("mouseover",function(){console.log("test");//1.创建对象const xhr = new XMLHttpRequest();//2.初始化 设置类型与URLxhr.open('POST', 'http://127.0.0.1:8000/server');//设置请求体//3.发送xhr.send('a=100&b=200');//post请求体放在send中//4.事件绑定xhr.onreadystatechange = function(){//判断if(xhr.readyState === 4){if(xhr.status >= 200 && xhr.status < 300){//处理服务端返回结果result.innerHTML = xhr.response;}}}})
</script>const express = require('express');
const app = express();
app.post('/server', (request, response) => {//设置响应头 允许跨域response.setHeader('Access-Control-Allow-Origin', '*'); //设置响应体response.send('hello post');
});
app.listen(8000, () => {console.log("服务已经启动,8000端口监听中");
});
响应状态码返回404的原因
1.url设置出错 (http://)
2.网络出现波动,请求错误
设置头信息
//写在open后面
//设置请求头
//Content-Type设置请求体内容类型 第二个''参数查询字符串的类型(固定写法)xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');//自定义 错误原因:在请求头中加入了自定义的头xhr.setRequestHeader('name','nidi');//解决方法:
//在js中加入 (设置自定义请求头服务器需设置)
//response.setHeader('Access-Control-Allow-Headers','*');
//并把类型变成all
const express = require('express');
const app = express();
app.all('/server', (request, response) => {//设置响应头 允许跨域response.setHeader('Access-Control-Allow-Origin', '*'); //响应头 可以自定义response.setHeader('Access-Control-Allow-Headers','*');//设置响应体response.send('hello post');
});
app.listen(8000, () => {console.log("服务已经启动,8000端口监听中");
});
服务端响应JSON数据
服务器响应也可以设置为一个数据发送过去,但是不能直接写,要通过JSON.stringify(数据)把数据转换为JSON字符串。因为resopnse.send()中只能写字符串
<div id="result">按下键盘按键反应</div><script>const result = document.getElementById('result');//绑定键盘按下事件window.onkeydown = function(){//发送请求const xhr = new XMLHttpRequest();//设置响应体数据类型xhr.responseText = 'json';//初始化xhr.open('GET','http://127.0.0.1:8000/json-server');//发送xhr.send();//事件绑定xhr.onreadystatechange = function(){if ( xhr.readyState === 4){if ( xhr.status >= 200 && xhr.status <= 300){// console.log(xhr.response);// result.innerHTML = xhr.response;
//页面拿到json响应体是无法直接识别的,需要将json字符串转化为js对象//1.手动对数据转化// let data = JSON.parse(xhr.response);// console.log(data);// result.innerHTML = data.name;//2.自动对数据转换//借助xhr.resopnseType = 'json';//在上面设置响应体数据类型console.log(xhr.response);result.innerHTML = data.name;}}}}</script>const express = require('express');
const app = express();
app.all('/json-server', (request, response) => {//响应头response.setHeader('Access-Control-Allow-Headers','*');//响应一个数据const data = {name: 'nidi'};//对对象进行字符串转换let str = JSON.stringify(data);//设置响应体response.send(str);
});
app.listen(8000, () => {console.log("服务已经启动,8000端口监听中");
});
网络请求超时及网络异常处理
服务端写个定时器,3s之后发送给响应体
const express = require('express');
const app = express();
app.all('/delay', (request, response) => {//响应头response.setHeader('Access-Control-Allow-Headers','*');//延时响应 3s做出响应setTimeout(() => {//设置响应体response.send('延时响应');}, 3000);});
app.listen(8000, () => {console.log("服务已经启动,8000端口监听中");
});
前端页面设置超时设置xhr.timeout = 2000
超时回调xhr.ontimeout 网络异常回调xhr.onerror
<button>点击发送</button><div id="result"></div><script>const btn = document.getElementsByTagName('button')[0];btn.addEventListener('click', function(){const xhr = new XMLHttpRequest();//超时设置 如果超时2s就取消xhr.timeout = 2000;//网络回调xhr.ontimeout = function(){alert('网络异常,请稍后重试');}//网络异常回调//onerror 错误监视器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>
手动取消请求
<button>点击发送</button><button>取消发送</button><script>const btns = document.querySelectorAll('button');let x = null;//发送按钮btns[0].onclick = function(){//发送请求x = new XMLHttpRequest();x.open("GET", 'http://127.0.0.1:8000/delay');x.send();}//abort 借助这个来取消请求btns[1].onclick = function(){x.abort();}</script>
nidi.js
定时发送的响应体
const express = require('express');
const app = express();
app.all('/delay', (request, response) => {//响应头response.setHeader('Access-Control-Allow-Headers','*');//延时响应 3s做出响应setTimeout(() => {//设置响应体response.send('延时响应');}, 3000);});
app.listen(8000, () => {console.log("服务已经启动,8000端口监听中");
});
请求重复发送问题
多次相同请求,只会给服务端发送一个请求
<button>点击发送</button><script>const btns = document.querySelectorAll('button');let x = null;//标识变量let nidi = false;//是否在发送AJAX请求btns[0].onclick = function(){//判断标识变量if ( nidi) x.abort();//如果正在发送,则取消该请求,创建一个新的请求x = new XMLHttpRequest();//修改标识变量值nidi = true;x.open("GET", 'http://127.0.0.1:8000/delay');x.send();x.onreadystatechange = function(){if(x.readyState === 4){//有可能请求失败,所以不用再做判断,只要拿到结果nidi = false;//拿到服务器的全部结果后,设置false}}}</script>
Axios发送AJAX请求
1.安装axios
npm i axios
2.在线引用
可以去BootCND上面找
< script crossorigin=“anonymous” src=“https://cdn.bootcdn.net/ajax/libs/axios/1.3.4/axios.min.js”>
配置服务器
const express = require('express');
const app = express();
//all方式 可以接受任意类型的请求
app.all('/axios-server', (request, response) => {//设置响应头 允许跨域response.setHeader('Access-Control-Allow-Origin', '*'); //响应头response.setHeader('Access-Control-Allow-Headers','*'); //设置响应体const data = {name:'nidi'};response.send(JSON.stringify(data));
});
app.listen(8000, () => {console.log("服务已经启动,8000端口监听中");
});
发送GET请求
const btns = document.querySelectorAll('button');btns[0].onclick = function(){//GET请求 决定给谁发axios.get('http://127.0.0.1:8000/axios-server',{//url参数params: {id: 100,vip: 7},headers: {name:'nidi',age:20}});}
tip:可用baseURL对url进行简化
//配置baseURL
axios.defaults.baseURL='http://127.0.0.1:8000';
axios.get('axios-server',{
});
数据返回是基于Promise的:
.then(value => {console.log(value);})
axios发送请求成功的值是一个封装好的响应对象
我们需要的响应数据藏在response.data中
发送POST请求
btns[1].onclick = function() {axios.post('http://127.0.0.1:8000/axios-server', {username: 'nidi',password: '1234'},{params: {id:100,vip: 7},headers: {height: 180,weight: 180,}});}
axios函数发送通用请求
btns[2].onclick = function (){axios({// 请求方法method: 'POST',// urlurl: 'http://127.0.0.1:8000/axios-server',// url参数params: {vip:10,level:30},// 头信息headers: {a:100,b:200},// 请求体data: {username: 'admin',password: 'admin'}}).then((response) =>{console.log(response);//全部响应结果console.log('响应状态码:', response.status);console.log('响应状态字符串:',response.statusText);console.log('响应头信息:', response.headers);console.log('响应体:', response.data);})}
总结
axios本质上是对原声XMLHttpRequest的封装,不需要复杂的步骤
1.创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
2.初始化,给定请求方式以及请求地址
xhr.open(“请求方式”, ulr地址);
3.发送请求
xhr.send();
4.获取服务器端给客户端的响应数据
现在只需要写axios.get或axios.post或通用请求
feth()函数发送AJAX请求
const btns = document.querySelector('button');btns.onclick = function () {//参数在fetch('http://127.0.0.1:8000/fetch-server?vip=10',{//请求方法method:'POST',//请求头headers:{name:'nidi'},//请求体body:'username=nidi&&password=1234'}).then(response => {return response.text();//如果服务端放回结果是json,就把text改为json,会自动解析成json对象}).then(response =>{console.log(response);});}
同源策略
网页ulr和ajax请求的目标资源的url的协议、域名、端口保持一致
违背同源策略就是跨域
//要从http://120.0.0.1:9000/home打开,这样才能做到9000端口同源
<h1>你弟啊</h1><button>点击获取用户数据</button><script>const btn = document.querySelector('button');btn.onclick = function(){const x = new XMLHttpRequest();//因为是同源策略,所有url可用简写x.open("GET",'/data');//发送x.send();x.onreadystatechange = function(){if (x.readyState === 4){if ( x.status >= 200 && x.status < 300){console.log(x.response);}}}}</script>const express = require('express');
const app = express();
app.get('/home', (request, response) => {response.sendFile(__dirname + '/nidi.html');
});
app.get('/data', (request, response) => {response.send('用户数据');
});
app.listen(9000, () => {console.log("服务已经启动,9000端口监听中");
});
解决跨域的方法
JSONP(非官方),只支持get请求
利用script标签的跨域能力来发送请求
CORS(官方),跨域资源贡献
不需要在客户端做任何操作,完成在服务器中进行处理
CORS通过设置一个响应头来告诉浏览器允许跨域
response.setHeader('Access-Control-Allow-Headers','*');
原生jsonp的实践
输入框失去焦点后,input变红,p显示文字
用户名: <input type="text" id="username"><p></p><script>//获取input元素const input = document.querySelector('input');const p = document.querySelector('p');//声明handl函数function handle(data){input.style.border = "solid 1px #f00";//修改p标签的提示文本p.innerHTML = data.msg}//绑定事件input.onblur = function(){//获取用户的输入值let username = this.value;//向服务端发送请求检查用户名是否存在//1.创建script标签const script = document.createElement('script');//2.设置标签的src属性script.src = 'http://127.0.0.1:8000/check-username';//3.将script插入到文档中(不插入就无法向服务端发送请求)//把script插入到body标签的最后document.body.appendChild(script);}</script>app.all('/check-username', (request,response) => {const data = {exist: 1,msg:'用户名已经存在'};//将数据转化为字符串let str = JSON.stringify(data);//返回结果response.end(`handle(${str})`);
});//还要再开一个8000端口
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
