文章目录
- 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 = nullbtn[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 = falsebtn[0].onclick = () => {if(isSending) x.abort()xhr = new XMLHttpRequest()isSending = truexhr.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', {//Urlparams: {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'}}, {//Urlparams: {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.valuelet 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')
}