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端口


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部