1.Ajax概述
1.1 AJAX 简介
AJAX 全称为Asynchronous JavaScript And XML,就是异步的JS 和XML
通过AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据
AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式
1.2 XML 简介
XML 可扩展标记语言。
XML 被设计用来传输和存储数据。
XML 和HTML 类似,不同的是HTML 中都是预定义标签,而XML 中没有预定义标签,全都是自定义标签,用来表示一些数据。
比如说我有一个学生数据:
name = “孙悟空” ; age = 18 ; gender = “男” ;
用XML 表示:
<student>
<name>孙悟空</name>
<age>18</age>
<gender>男</gender>
</student>
现在已经被JSON 取代了。
{"name":"孙悟空","age":18,"gender":"男"}
1.3 AJAX 的特点
优点
可以无需刷新页面而与服务器端进行通信
允许你根据用户事件来更新部分页面内容
缺点
没有浏览历史,不能回退
存在跨域问题(同源)
SEO 不友好
2. HTTP相关问题
2.1 MDN 文档
developer.mozilla.org/zh-CN/docs/…
2.2 HTTP 请求交互的基本过程
前后应用从浏览器端向服务器发送HTTP 请求(请求报文)
后台服务器接收到请求后, 调度服务器应用处理请求, 向浏览器端返回HTTP响应(响应报文)
浏览器端接收到响应, 解析显示响应体/调用监视回调
2.3 HTTP 请求报文
2.4 HTTP 响应报文
2.5 post 请求体参数格式
Content-Type: application/x-www-form-urlencoded;charset=utf-8
用于键值对参数,参数的键值用=连接, 参数之间用&连接
例如: name=%E5%B0%8F%E6%98%8E&age=12
Content-Type: application/json;charset=utf-8
用于 json 字符串参数
例如: {"name": "%E5%B0%8F%E6%98%8E", "age": 12}
Content-Type: multipart/form-data
用于文件上传请求
2.6 常见的响应状态码
200 OK 请求成功。一般用于GET 与POST 请求
201 Created 已创建。成功请求并创建了新的资源
401 Unauthorized 未授权/请求要求用户的身份认证
404 Not Found 服务器无法根据客户端的请求找到资源
500 Internal Server Error 服务器内部错误,无法完成请求
2.7 不同类型的请求及其作用
GET: 从服务器端读取数据(查)
POST: 向服务器端添加新数据 (增)
PUT: 更新服务器端已经数据 (改)
DELETE: 删除服务器端数据 (删)
3.搭建服务端
3.1 NodeJS的安装与介绍
下载网址:nodejs.cn/download/
3.2 express框架介绍与基本使用
安装插件
npm i express
新建index.js
const express = require('express')
const app = express()
app.get('/',(req,res)=>{
res.setHeader("Access-Control-Allow-Origin", "*")
res.send('ok')
})
app.listen(8080,()=>{
console.log('listening 8080');
})
启动
node index.js
4.AJAX请求
4.1 发送get请求
前端代码
<button id="btn">点击发送请求</button>
<script>
const btn = document.getElementById('btn')
btn.onclick = ()=>{
//1创建对象
const xhr = new XMLHttpRequest()
//2.初始化 请求类型,url,参数
xhr.open('get','http://127.0.0.1:8080?a=100&b=200')//设置参数
//3.发送
xhr.send()
//4.事件绑定
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4) {
if(xhr.status>=200 && xhr.status<300){
document.write(xhr.response)
}
}
}
}
</script>
4.3 发送POST请求
const xhr = new XMLHttpRequest()
xhr.open('post','http://127.0.0.1:8080')
xhr.send('a=100&b=200')
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4) {
if(xhr.status>=200 && xhr.status<300){
document.write(xhr.response)
}
}
}
4.4设置请求头信息
前端代码xhr.setRequestHeader
btn.onclick = ()=>{
const xhr = new XMLHttpRequest()
xhr.open('post','http://127.0.0.1:8080')
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded')
xhr.setRequestHeader('name','xiaoming')
xhr.send()
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4) {
if(xhr.status>=200 && xhr.status<300){
document.write(xhr.response)
}
}
}
}
后端要设置响应头res.setHeader
app.all('/',(req,res)=>{
res.setHeader("Access-Control-Allow-Origin", "*")
res.setHeader("Access-Control-Allow-Headers", "*")
res.send('ok')
})
4.5 服务端响应JSON数据
后端返回数据代码字符串对象
app.all('/',(req,res)=>{
res.setHeader("Access-Control-Allow-Origin", "*")
res.setHeader("Access-Control-Allow-Headers", "*")
res.send(JSON.stringify({
name:'小明'
}))
})
方法一:手动对数据转换JSON.parse
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4) {
if(xhr.status>=200 && xhr.status<300){
let data = JSON.parse(xhr.response)
document.write(data.name)
}
}
}
方法二:自动转换,设置xhr.responseType='json'
const xhr = new XMLHttpRequest()
xhr.open('post','http://127.0.0.1:8080')
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded')
xhr.setRequestHeader('name','xiaoming')
xhr.responseType='json'
xhr.send()
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4) {
if(xhr.status>=200 && xhr.status<300){
document.write(xhr.response.name)
}
}
}
5.nodemon自动重启工具安装
npm i -g nodemon
nodemon ./index.js
nodemon运行 提示错误:无法加载文件 C:\Users…\AppData\Roaming\npm\nodemon.ps1,因为在此系统上禁止运行脚本。
这是你机子禁止运行脚本,解决办法
1.管理员身份打开powerShell
2.输入set-ExecutionPolicy RemoteSigned
如果未成功,提示如下内容
……内容省略……
要更改当前用户的执行策略,请运行 "Set-ExecutionPolicy -Scope CurrentUser"。
// 这实际上是管理员运行的意思
……内容省略……
那么输入Set-ExecutionPolicy -Scope CurrentUser运行即可,之后输入RemoteSigned回车运行即可,再次执行nodemon,发现成功了
6.IE缓存问题解决
添加时间戳
xhr.open('GET', 'http://127.0.0.1/?t=' + new Date())
7.异常处理
7.1 AJAX请求超时与网络异常处理
超时设置xhr.timeout
错误处理回调xhr.ontimeout
const xhr = new XMLHttpRequest();
xhr.timeout = 2000
xhr.ontimeout = ()=>{
alert('error')
}
xhr.onerror = ()=>{
alert('network error')
}
xhr.open('GET', 'http://127.0.0.1/')
xhr.send()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
document.write(xhr.response)
}
}
}
7.2 AJAX取消请求 xhr.abort()
<script>
const el = document.getElementById('send')
const el1 = document.getElementById('cancel')
const xhr = new XMLHttpRequest();
el.onclick = () => {
xhr.open('GET', 'http://127.0.0.1/')
xhr.send()
}
el1.onclick = () => {
xhr.abort()
}
</script>
7.3 AJAX请求重复发送问题
const xhr = new XMLHttpRequest();
let isSending = false
el.onclick = () => {
if (isSending) {
xhr.abort()
}
isSending = true
xhr.open('GET', 'http://127.0.0.1/')
xhr.send()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
isSending = false
}
}
}
8.发送AJAX请求方式
8.1 jQuery发送AJAX请求
get请求,返回来的数据以json格式显示
$.get('http://127.0.0.1/',{a:100,b:100},(res)=>{
console.log(res);
},'json')
post请求,返回来的数据以json格式显示
$.post('http://127.0.0.1/',{a:100,b:100},(res)=>{
console.log(res);
},'json')
ajax请求,通用求求,相比上面两种方式,可以配置更多的请求信息
$.ajax({
url:'http://127.0.0.1/',
headers:{name:'1234'}, // 请求头部信息
data:{ 1:100,b:200}, //请求体数据
type:'GET',
dataType:'json',
timeout:2000,
success:(res)=>{
console.log(res);
},
error:(err)=>{
console.log('出错啦');
}
})
8.2 Axios发送AJAX请求
get请求
axios.get('http://127.0.0.1/server',{
// URL参数
params:{
id:234,
vip:10
},
// 请求头参数
headers:{
name:'xiaoming',
age:20
}
}).then(res=>{
console.log(res);
})
post请求,注意请求体data的位置
axios.post('http://127.0.0.1/server', {
username: 'xiaoming'
}, {
// URL参数
params: {
id: 234,
vip: 10
},
// 请求头参数
headers: {
name: 'xiaoming',
age: 20
},
}).then(res => {
console.log(res);
})
通用请求
axios({
// 请求方法get,post
method: 'get',
url: 'http://127.0.0.1/server',
// URL参数
params: {
name: 'xiaoming'
},
// 头信息
headers: {
vip: 10
},
// 请求体参数
data: {
password: 123
}
}).then(res=>{
console.log(res);
})
8.3 使用fetch函数发送AJAX请求
fetch参考文档:developer.mozilla.org/zh-CN/docs/…
fetch('http://127.0.0.1/server?vip=10', {
method: 'POST',
headers: {
name: 'xiaoming'
},
body: 'username=admin&password=123'
}).then(Response => {
return Response.text()
}).then(Response => {
console.log(Response);
})
9.跨域
9.1 jsonp
1)jsonp是什么
jsonp 是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get请求
2)jsonp是怎么工作的
在网页有一些标签天生具有跨域能力,比如link, iframe,script,jsonp就是利用script标签的跨域能力来发送请求的
9.2 原生jsonp实践
后端返回的结果需要是一段可执行的代码
//后端返回
app.all('/server', (req, res) => {
res.send('console.log("hello world")')
})
// 后端返回调用函数
app.all('/server', (req, res) => {
res.send('handle("hello world")')
})
// 前端处理函数
<script>
function handle(data) {
console.log(data)
}
</script>
<script src="http://127.0.0.1/server"></script>
9.3 jQuery发送jsonp请求
接口返回设置
app.all('/server', (req, res) => {
const c = req.query.callback
res.send(`${c}(234)`)
})
前端代码
<script>
const a = document.getElementById('a')
a.onclick = () =>{
$.getJSON('http://127.0.0.1/server?callback=?',(res)=>{
console.log(res);
})
}
</script>