文章目录
- 1. 前置知识
- 1.1 ajax 介绍
- 1.2 XML 简介
- 2. AJAX 学习
- 2.1 AJAX基础学习
- (1)AJAX的特点
- (2)AJAX 初体验
- (3)服务端响应json 数据
- 2.2 IE 缓存问题
- 2.3 请求超时和网络异常
- 2.4 手动取消请求
- 2.5 重复请求
- 2.6 jQuery 中的AJAX
- 2.7 axios 中的AJAX
- 2.8 fetch() 发送AJAX
- 3. 跨域
- 3.1 同源策略
- 3.2 如何解决跨域
- (1)JSONP
- (2)CORS
1. 前置知识
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 取代了
json({
name:'孙悟空',
age:18,
gender:'男'
})
2. AJAX 学习
2.1 AJAX基础学习
(1)AJAX的特点
- AJAX的优点
- 可以无需刷新页面而与服务器端进行通信;
- 允许你根据用户事件来更新部分页面内容。
- AJAX的缺点
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO不友好
(2)AJAX 初体验
**readystate:**是xhr对象中的属性,有0,1,2,3,4五个属性值;
- 0:xhr 对象还未初始化完成;
- 1:open()调用完成
- 2:send()调用完成
- 3:返回部分响应结果
- 4:服务已返回全部响应结果
onreadystatechange
事件就是指readystate改变一次就触发一次事件
let btn = document.getElementsByTagName('button')[0]
let result = document.getElementById('result')
btn.onclick = () => {
// 创建ajax 请求
// 1. 创建xhr 对象
const xhr = new XMLHttpRequest()
// 2. 初始化 设置请求方法和url
xhr.open('GET','http://127.0.0.1:8000/server')
// 3. 发送
xhr.send()
// 4. 事件绑定 处理服务端返回的结果
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
// console.log(xhr.status);
// console.log(xhr.statusText);
// console.log(xhr.getAllResponseHeaders);// 获取全部响应头内容
// console.log(xhr.response);// 获取响应体内容
result.innerHTML = xhr.response
}
}
}
}
- get()
// 2. 初始化 设置请求方法和url
xhr.open('GET','http://127.0.0.1:8000/server')
- post()
// 2. 初始化 设置请求方法和url
xhr.open('POST','http://127.0.0.1:8000/server')
- 设置请求头
xhr.setRequestHeader('name','cherry')
(3)服务端响应json 数据
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
// console.log(xhr.status);
// console.log(xhr.statusText);
// console.log(xhr.getAllResponseHeaders);// 获取全部响应头内容
// console.log(xhr.response);// 获取响应体内容
result.innerHTML = xhr.response
}
}
}
2.2 IE 缓存问题
IE 浏览器存在一个问题:就是某个网站第二次刷新时会将缓存中的内容拿过来,也就是如果第一次刷新后我们更新了形影提数据,那么该网站在ie浏览器中呈现时将不会得到刷新后的内容,对于这种问题我们可以使用时间戳
来实现。
xhr.open('post','http://127.0.0.1:8000/ie?t='+Date.now())
2.3 请求超时和网络异常
const xhr = new XMLHttpRequest()
// 超时设置
xhr.timeout = 2000// ms 2s之后无结果响应就不在向下执行
xhr.ontimeout=()=>{
alert('网络异常')
}
xhr.onerror=()=>{
alert('网络连接异常')
}
2.4 手动取消请求
上小节我们尝试了自动取消请求,这节来学习手动取消请求。
let btn =document.querySelectorAll('button')
let xhr = null
btn[0].onclick=()=>{
xhr = new XMLHttpRequest()
xhr.open('GET','http://127.0.0.1:8000/delay')
xhr.send()
}
btn[1].onclick=()=>{
xhr = new XMLHttpRequest()
xhr.abort()
}
2.5 重复请求
上个请求未响应就发送下个请求,服务器就需要频繁去处理,我们一般设置先去查询是否有相似的请求发送,如果有就先关闭上次请求,再发送新的请求。
let btn = document.querySelectorAll('button')
let xhr = null
// 标识变量
let isSending = false
btn[0].onclick = () => {
if(isSending) x.abort()
xhr = new XMLHttpRequest()
isSending = true
xhr.open('GET', 'http://127.0.0.1:8000/delay')
xhr.send()
xhr.onreadystatechange=()=>{
if(xhr.readyState === 4){
isSending=false
}
}
}
btn[1].onclick = () => {
xhr.abort()
}
2.6 jQuery 中的AJAX
$('button').eq(0).click(()=>{
$.get('http://127.0.0.1:8000/jquery',{a:100,b:20},(data)=>{
console.log(JSON.parse(data));// data指的是响应体
},'json')
// 第二个参数设置的是请求参数
// 第四个参数设置的是响应格式
})
$('button').eq(1).click(()=>{
$.post('http://127.0.0.1:8000/jquery',{a:100,b:20},(data)=>{
console.log(data);// data指的是响应体
})
})
// 自定义程度强时使用ajax()
$('button').eq(2).click(()=>{
$.ajax({
url:'http://127.0.0.1:8000/delay',
data:{a:100,b:20},// 请求参数
type:'GET',// type/method 都可以
// 响应体结果
dataType:'json',
// 成功的回调
success:(data)=>{
console.log(data);
},
timeout:2000,// ms 超时时间
error:()=>{
console.log('出错了');
},
// 请求头信息
headers:{
d:100,
b:20
}
})
})
2.7 axios 中的AJAX
// 配置之后 下面的get和post请求的路径会与之拼接
axios.defaults.baseURl = 'http://127.0.0.1:8000'
const btns = document.querySelectorAll('button')
btns[0].onclick = () => {
axios.get('/axios-server', {
//Url
params: {
id: 100,
cherry: 1
},
headers: {
name: 'cherry',
CharacterData: 'new bee'
}
}).then(value => {
// axios 使用then() 返回响应体
console.log(value);
})
}
btns[1].onclick = () => {
axios.post('/axios-server', {
//请求体
data: {
name: 'cherry',
CharacterData: 'new bee'
}
}, {
//Url
params: {
id: 100,
cherry: 1
},
//请求头
headers: {
name: 'cherry',
CharacterData: 'new bee'
}
}).then(value => {
// axios 使用then() 返回响应体
console.log(value);
})
}
// axios函数发送请求
btns[2].onclick = () => {
axios({
method: 'post',
url: '/axios-server',
params: {
a: 100,
b: 200
},
headers: {
name: 'cherry',
purpose: '养好作息!认真学习'
},
data: {
name: 'cherry',
purpose: '养好作息!认真学习'
}
}).then(response => {
console.log('养好作息!认真学习');
})
}
2.8 fetch() 发送AJAX
let btn = document.querySelector('button')
btn.onclick = () => {
fetch('http://127.0.0.1:8000/fetch-server?cherry=NO.1',{
method: 'POST',
headers: {
name: 'cherry',
purpose: 'early to bed and early to up'
},
body: 'name=cherry&purpose=early to bed and early to up'
}).then(response => {
return response.text()
// return response.json()
})
}
3. 跨域
3.1 同源策略
同源策略(Same-Origin Policy)最早由Netscape公司提出,是浏览器的一种安全策略。
同源:协议
、域名
、端口号
必须完全相同。(当前页面和ajax 请求两者之间)
违背同源策略就是跨域。
3.2 如何解决跨域
(1)JSONP
JSONP是什么
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明
才智开发出来,只支持get请求
。
JSONP怎么工作的?
在网页有一些标签天生具有跨域能力,比如:< img>< link>< iframe>< script> 。
JSONP就是利用script标签的跨域能力来发送请求的。
原生JSONP的使用
- 动态的创建一个script标签
var script = document.createElement("script");
- 设置script的src,设置回调函数
script.src = "http://localhost:3000/testAJAX?callback=abc";
检测用户名是否可用
username:<input type="text" name="username" id="">
<p></p>
<script>
const username = document.querySelector('input')
const p= document.querySelector('p')
function handle(data){
p.innerHTML=data.msg
}
username.onblur = ()=>{
let data = this.value
let script = document.createElement('script')
script.src = 'http://127.0.0.1:8000/checkUsername'
document.body.appendChild(script)
}
app.get('/checkUsername', (req, res) => {
data = {
name: 'cherry',
msg:'NO USE'
}
str = JSON.stringify(data)
// script 标签发请求时 send() 返回的内容应该是js 代码
res.send(`handle(${str})`)
})
使用jQuery 发送JSONP 请求
$('button').eq(0).click(() => {
// 这个地方要注意 使用jsonp 发送请求 Url参数必须要有callback=? 固定语法
$.getJSON('http://127.0.0.1:8000/jsonpTest?callback=?', function (data) {
$('#test') .html(`
name:${data.name},<br>
msg:${data.msg}
`)
})
})
(2)CORS
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access control CORS
CORS是什么?
CORS(Cross–Origin Resource Sharing),跨域资源共享。CORS是官方
的跨域解决方
案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理
,支持
get和post请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些
源站通过浏览器有权限访问哪些资源
CORS怎么工作的?
CORS是通过设置一个响应头
来告诉浏览器,该请求允许跨域,浏览器收到该响应
以后就会对响应放行。
CORS的使用
主要是服务器端的设置:
router.get("/testAJAX", (req,res)=>{
res.setHeader('Access-Control-Allow-Origin','*')
res.send('hello')
}