目录
ajax介绍
AJAX全称为Asynchronous JavaScript And XML,就是异步的JS和XML。
通过AJAX可以在浏览器中向服务器发送异步请求
最大的优势:无需刷新获取数据
应用:
搜索栏输入关键字显示提示信息、登录界面输入用户名显示已存在、滚动下拉条懒加载信息……
XML介绍
XML 可扩展标记语言
XML 被设计用来传输和存储数据 HTML 呈现数据
XML 和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全部都是自定义标签,用来表示一些数据
例如:
有一个学生数据:
name="孙悟空";age=18;gender="男"
用XML表示:
<student>
<name>孙悟空</name>
<age>18</age>
<gender>男</gender>
</student>
现在已被JSON取代了。
灵活方便
用JSON表示:
{"name":"孙悟空","age":"18","gender":"男"}
AJAX的特点
-
ajax的优点
a. 可以无需刷新页面与服务器端进行通信;
b. 允许你根据用户事件来更新页面部分内容。
-
ajax的缺点
a. 没有浏览历史,不能回退
b. 存在跨域问题(同源)
c. SEO不友好(SEO:搜索引擎优化)爬虫爬取不到
注:当向服务端请求数据时,服务端返回结果,直接通过浏览器端JS动态创建数据,而不将结果放在响应体中
HTTP
HTTP(hypertext transport protocol)协议【超文本传输协议】,协议详细规定了浏览器和万维网服务器之间互相通信的规则
请求报文
格式与参数
行 请求类型 字符编码 HTTP协议版本 头 地址,Cookie,内容类型,用户代理商 空行 必须 体 发送的内容
##响应报文
行 HTTP版本 响应状态码 响应状态字符串 头 。。。 空行 必须 体 返回结果 比如:<html> <head></head> <body> <h1>张三</h1> </body> </html>
Express框架
Express简介
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具
使用 Express 可以快速地搭建一个完整功能的网站。
Express框架核心特性:
-
可以设置中间件来响应 HTTP 请求。
-
定义了路由表用于执行不同的 HTTP 请求动作。
-
可以通过向模板传递参数来动态渲染 HTML 页面。
express安装
1. 初始化packagenpm init --yes
2. 安装expressnpm i express
express使用
1. 引入express
const express = require('require');
2. 创建实例对象
const app = express();
3. 创建路由规则
//request 是对请求报文的封装
//response 是对响应报文的封装
app.get('/',(request,response)=>{
//设置响应
response.send("hello express");
});
4. 监听端口启动服务
app.listen(3000);
Ajax发送请求
原生js发送Ajax请求
浏览器端
<body>
<button>按钮</button>
<div id="box1">
</div>
<script>
let btn = document.getElementsByTagName('button')[0];
let box1 = document.getElementById('box1');
btn.onclick = function () {
1、创建请求对象
XMLHttpRequest: 参数1:请求方式 参数2:url
const xhr = new XMLHttpRequest();
2、初始化,设置请求方法和url
xhr.open('GET', 'http://127.0.0.1:8000/serves');
设置url参数:http://127.0.0.1:8000/serves?a=100&b=200&c=300
3、发送
xhr.send();
4、事件绑定 处理服务端返回的结果
onreadystatechange
1、on: when 当……时候
2、readystate 是xhr对象中的属性,
表示状态:0 1 2 3 4
0:默认值
1:初始化完毕
2:发送请求完毕
3:返回了部分结果
4:返回了所有结果
3、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);
box1.innerHTML = xhr.responseText;
} else {
}
}
}
}
</script>
</body>
服务端
const { response } = require('express');
const express = require('express');
const app = express();
app.get('/serves',(request,response)=>{
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
//设置响应体
response.send("hello express");
})
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中....")
})
效果
Axios发送Ajax请求
浏览器端
1.引入axios.js
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.26.1/axios.js"></script>
<!--crossorigin="anonymous" 避免报文警告 -->
2.axios的三种请求方式
<body>
<button id="btn01">GET</button>
<button id="btn02">POST</button>
<button id="btn03">AJAX</button>
<script>
let btns = document.querySelectorAll('button');
配置baseURL(简化URL信息)
axios.defaults.baseURL = 'http://127.0.0.1:8000';
GET请求
btns[0].onclick = function () {
axios.get('/axios-server', {
url参数
params: {
id: 100,
vip: 7
},
请求头信息
headers: {
name: 'zhangsan',
age: 18
}
}).then(value => console.log(value));
}
axios.post(url,data(请求体),其它)
btns[1].onclick = function () {
axios.post('/axios-server', {
username: 'admin',
password: 'admin'
}, {
url参数
params: {
id: 108,
ip: 5
},
请求头
headers: {
weight: 180,
height: 180
}
})
}
axios({}),通过调用axios函数
btns[2].onclick = function () {
axios({
请求方法
method: 'POST',
url
url: '/axios-server',
请求url参数
params: {
id: 345,
leval: 30
},
请求头
headers: {
content1: 'qingqiu',
content2: 'qingqiu2'
},
请求体参数
data: {
name: 'zhangsan',
gender: '男'
}
处理结果
}).then((response) => {
//输出全部响应信息
// console.log(response);
//响应头
console.log(response.headers);
//响应体
console.log(response.data);
//响应状态码
console.log(response.status);
//响应状态字符串
console.log(response.statusText)
})
}
</script>
</body>
服务端
const { response } = require('express');
const express = require('express');
const app = express();
app.all('/axios-server',(request,response)=>{
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
response.setHeader('Access-Control-Allow-Headers','*');
//设置响应体
const data = {name:'张三',age:18}
response.send(JSON.stringify(data));
})
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中....")
})
fetch函数发送Ajax请求
浏览器端
<body>
<button id="btn">AJAX</button>
<script>
let btn = document.getElementById('btn');
btn.onclick = function () {
fetch('http://127.0.0.1:8000/fetch-server', {
请求方法
method: 'POST',
请求头
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
请求体 字符串
body: 'username=admin&password=admin'
}).then(response => {
//获得响应体里的内容
// return response.text();
返回一个JSON对象
return response.json();
}).then(response => {
console.log(response);
})
}
</script>
</body>
服务端
const express = require('express');
const app = express();
app.post('/fetch-server',(request,response)=>{
response.setHeader('Access-Control-Allow-Origin','*');
// response.setHeader('Access-Control-Allow-Headers','*');
let data = {
name:'李四',
age:20
}
let str = JSON.stringify(data);
response.send(str);
})
app.listen(8000,()=>{
console.log('服务启动成功')
})
请求方式
get请求
app.get('/server',(req,res)=>{
//设置允许跨域
res.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
res.send("hello");
})
post请求
app.post('/server',(request,response)=>{
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
response.send("hello");
})
XMLHttpRequest
1.创建请求对象
const xhr = new XMLHttpRequest();
设置响应体数据类型 为json
xhr.responseType = "json"
2.初始化,设置请求方法和URL 设置url参数(?a=12&b=20)
xhr.open('GET/OPEN','http://127.0.0.1:8000/server?a=12')
设置请求头
参数1:请求头名字(表示请求体的类型) 参数2:请求体的格式 xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); 作用:表示客户端提交给服务器文本内容的编码方式 是URL编码 2、自定义请求头 xhr.setRequestHeader('name','zhangsan'); 注: 在自定义请求头中,若请求的方式是POST请求,则all可以接收任意的请求头,当自定义请求头,接收方式变为OPTINS,若设置为POST将接收不到请求的信息 app.all('/server',(request,response)=>{ response.setHeader('Access-Control-Allow-Origin','*'); //设置请求的方式为GET、POST均可 response.setHeader('Access-Control-Allow-Headers','*'); response.send("fair day!"); })
3.发送请求
xhr.send();
发送请求体
xhr.send('a:100&b:200&c:300'); xhr.send('a=100&b=200&c=300'); xhr.send(123445);
4.事件绑定 处理服务端返回的结果
xhr.onreadystatechange = function() { if(xhr.readyState === 4){ if(xhr.status >=200 && xhr.status<300){ result.innerHTML = xhr.response; } } }
JSON响应
服务端
app.post('/server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
//响应一个数据
let data = {
name: '张三-3'
}
//对对象进行字符串转换
let str = JSON.stringify(data);
response.send(str);
});
浏览器端
手动转换成对象
let data = JSON.parse(xhr.response);
自动转换成对象
xhr.responseType = "json";
IE缓存
问题:
当每次发出请求时,IE浏览器会比较,若访问的是同一个URL,则会走本地缓存
解决:加一个时间戳
xhr.open('POST','http://127.0.0.1:8000/ie?t='+Date.now());
请求超时与网络异常
请求超时
超时设置 2s xhr.timeout = 2000 超时回调 xhr.ontimeout = function(){ alert('网络异常,请重新尝试'); }
网络异常
网络出现异常 xhr.onerror = function(){ alert('你的网络似乎出现了问题'); }
服务端
app.post('/delay',(request,response)=>{
response.setHeader('Access-Control-Allow-Origin','*');
setTimeout(()=>{
response.send("网络异常")
},3000);
})
取消请求
xhr.abort();
<body>
<button id="btn01">发送请求</button>
<button id="btn02">取消请求</button>
<div id="box1"></div>
<script>
const btn01 = document.getElementById('btn01');
const btn02 = document.getElementById('btn02');
const box1 = document.getElementById('box1');
let xhr = null;
btn01.onclick = function () {
xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8000/delay');
xhr.send();
}
abort 配合超时响应使用
btn02.onclick = function () {
xhr.abort();
}
</script>
</body>
请求重复发送请求
目的:减轻服务器压力
<body>
<button id="btn01">发送请求</button>
<button id="btn02">取消请求</button>
<div id="box1"></div>
<script>
const btn01 = document.getElementById('btn01');
const btn02 = document.getElementById('btn02');
const box1 = document.getElementById('box1');
let xhr = null;
let isTrue = false;//表明ajax是否在发送请求
//false:没有发送
//true:正在发送
btn01.onclick = function(){
if(isTrue) xhr.abort();
//如果正在发送,则取消该请求,创建一个新的请求
xhr = new XMLHttpRequest();
isTrue = true;
xhr.open('GET','http://127.0.0.1:8000/delay');
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
isTrue = false;
// if(xhr.status>=200 && xhr.status<300){
// box1.innerHTML = xhr.response;
// }
}
}
}
//abort 配合超时响应使用
btn02.onclick = function(){
xhr.abort();
}
</script>
</body>
跨域
同源策略
浏览器同源政策及其规避方法 - 阮一峰的网络日志 (ruanyifeng.com)
同源策略(Same-Origin Policy)最早由 Netscape 公司提出,是浏览的一种安全策略。
同源:协议、域名、端口号 必须完全相同。
网页和发送请求的内容 来自同一个地方
违背同源策略就是跨域。
为什么要进行跨域? 单台服务器服务是有上限的 满足同源策略,url可以简写 xhr.open('GET','/data');
如何解决跨域?
jsonp
1)JSONP是什么?
一个跨域解决方案,只支持get请求
2)JSONP怎么工作的?
在网页有一些标签天生具有跨域能力,比如:img link iframe script
JSONP就是利用script标签的跨域能力来发送请求的
3)JSONP的使用
1.动态的创建一个script标签
var script = document.createElement("script");
2.设置script的src,设置回调函数
script.src = "http://localhost:3000/testAJAX?callback=abc"
回调函数
3.将script放入页面
浏览器端
<body>
<!-- jsonp只对get请求有效 -->
<!-- 响应js代码(函数) -->
<div id="result"></div>
<script>
//处理数据
function handle(data){
//获取result元素
let result = document.getElementById('result');
result.innerHTML = data.name;
}
</script>
<script src="http://127.0.0.1:8000/jsonp-server"></script>
</body>
服务端
const express = require("express");
const app = express();
app.get('/jsonp-server',(request,response)=>{
// response.send('console.log("hello world!")');
let data={
name:'zhangsan'
}
//将数据转化为字符串
let str = JSON.stringify(data);
//返回结果 response.end相当于break
返回的是一个JS表达式,供浏览器解析
response.end(`handle(${str})`);
})
//
app.get('/check-username',(request,response)=>{
// response.send('console.log("hello world!")');
let data={
exist:1,
msg:'用户名已存在...'
}
//将数据转化为字符串
let str = JSON.stringify(data);
//返回结果 response.end相当于break
response.end(`handle(${str})`);
})
app.listen(8000,()=>{
console.log("服务启动成功...");
})
cors
1). CORS是什么?
CORS (Cross Origin Resource Sharing),跨域资源共享。
特点:不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get请求和post请求
2). CORS怎么工作的?
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应就会对响应放行
3). CORS的使用
主要是服务端的设置(Access-Control-Allow-Origin)
app.post('/',(request,response)=>{
response.setHeader('Access-Control-Allow-Origin','*');
response.send("hello");
});