Ajax学习笔记
分为原生、jQuery、ffetch、axios四种
1.原生Ajax
1.1Ajax简介
是异步的JS和XML,通过AJAX可以在浏览器中发送异步请求,最大优势:页面无刷新获取数据。例如登录验证,今日头条,淘宝网页,用才会懒加载,又称按需加载(向服务器发出请求)。
1.2XML简介
xml 可扩展标记语言,被设计用来传输和存储数据,全都是自定义标签,用来表示一些数据,已被JSON取代。
1.3Ajax特点
1.3.1Ajax的优点
-
无需刷新页面与服务器通信
-
允许根据用户时间来更新部分页面内容
1.3.2Ajax的缺点
-
没有浏览历史
-
存在跨域问题(可解决)
-
SEO(搜索引擎优化)不友好
1.4HTTP
(hypertext transfport protocol) 超文本传输协议,详细规定了浏览器和万维网服务器之间互相通信的约定,规则。
1.4.1请求
请求报文格式与参数
-
请求行
GET.../url /http版本
-
请求头
Host: Cookie: Content-type:
-
请求空行
-
请求体
Post请求可以不为空
1.4.2响应
响应报文格式与参数
-
请求行
http版本/响应状态码200/响应状态字符串OK
-
请求头
Content-type:text/html;charset=utf-8 Content-length:2048 Content-encoding:gzip
-
请求空行
必须有
-
请求体
html的内容在此放置会被解析
2.AJAX-NodeJs的安装与介绍
2.1 安装NodeJs
为Ajax提供一个服务器环境
2.2 Express框架
Express基本使用
npm init --yes //npm初始化 npm i express //安装express插件
-
引入express
const express = require('express')
-
创建应用对象
const app = express();
-
创建路由规则
app.get('/',(request,response) => { response.send('hello express'); });
-
监听端口启动服务
app.listen(8000,()=> { console.log('服务已经启动,8000端口监听中...') })
2.2 Ajax基本操作
2.2.1 Ajax创建
-
创建http对象
const xhr = new XMLHttpRequest();
-
初始化,设置GET请求方法和url
xhr.open('GET', 'http://127.0.0.1:8000/hello');
-
发送
xhr.send();
-
事件绑定,处理服务器返回的结果
//on 就是当...时 //readyState 是xhr对象的属性,表示状态 0 1 2 3 4 //change 改变 xhr.onreadystatechange = function () { //判断(服务器是否返回了所有结果以及响应状态码 ) if(xhr.readyState == 4 && xhr.status == 200) { //处理结果 console.log(xhr.status);//状态码 console.log(xhr.statusText);//状态字符串 console.log(xhr.getAllResponseHeaders());//所有响应头 console.log(xhr.response);//响应体 } }
2.2.2 Ajax设置请求参数
浏览器上在url后用“?”分割,( 参数名=参数值);若有多个参数,使用“&”连接
2.2.3 Ajax传递post请求
hello.js app.post('URL',(request,response) => { //设置请求头 , 设置允许跨域 response.setHeader("Access-Control-Allow-Origin") //设置响应体 response.send('hello Ajax post'); });
2.2.4 Ajax设置post请求参数
在send()当中设置,意味着向服务器已发送参数
xhr.send('a=100&b=200&c=300')//第一种方式 xhr.send('a:100&b:200&c:100')//第二种 xhr.send('12324351')//也可以这样传参,需要注意服务端必须要有处理逻辑
2.2.5 Ajax设置请求头信息(可自定义)
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')//头名用来设置请求体内容类型,值是头参数查询字符串类型,为固定写法 // hello.js中需设置响应头 response.setHeader('Access-Control-Allow-Headers','*');
2.3 Ajax服务端响应JSON数据
hello.js
app.all('/json-hello', (request, response) => { response.setHeader('Access-Control-Allow-Origin','*'); response.setHeader('Access-Control-Allow-Headers','*'); //响应一个JSON数据 const data = { name:'hello' }; //对对象进行字符串转换 let str = JSON.stringfy(data); response.send(str) response.send('hello ajax post'); });
Json.html
由于服务器此时返回结果是一个字符串,可使用两种方法进行数据转化
//hello.js response.send(JSON.stringify(data)); //前端手动对数据转化 let data =JSON.parse(xhr.response) console.log(data) //前端自动转换(设置响应体数据的类型) xhr.responseType = 'json'
2.4Ajax-nodemon自动重启服务工具
该工具可以实现自动重启node服务
//安装 node i -g nodemon //使用,会自动补齐路径 nodemon hello.js
3 Ajax常见问题
3.1请求超时与异常处理
hello.js
//延时3s响应 app.get('/delay', (request, response) => { response.setHeader('Access-Control-Allow-Origin','*'); setTimeout(()=> { //设置响应体 response.send('延时响应'); },3000) });
前端页面
//超时设置2s,即若响应超过2s即取消响应 xhr.timeout = 2000; //超时回调 xhr.ontimeout = function() { //给出用户提醒,此处alert仅为演示,实际开发中会使用div、遮罩层等更为友好的方式,例如阅微园中的“404页面处理” alert("网络异常,请稍后重试!") } //网络异常回调设置 xhr.onerror = function() { alert('你的网络似乎出了一些问题!') }
3.2手动取消请求
ajax提供了一个abort()方法用于手动取消请求
3.3 请求重复发送问题
请求重复问题是用户在发送请求时通过不断点击等操作使得服务器需要不断响应请求,从而导致服务器压力剧增。为解决该问题可采用设置标识变量的方法
let xhr = null; //标识变量 let isSending = false; // 默认设置为未发送请求,true代表已发送 btn.addEventListener('click', ()=> { if(isSending) xhr.abort(); xhr = new XMLHttpRequest(); // 修改 标识变量的值 isSending = true; xhr.open("GET", 'http://127.0.0.1:8000/delay'); xhr.send(); // 在请求发送后修改标识变量 xhr.onreadystatechange = function () { //判断(服务器是否返回了所有结果以及响应状态码 ),此处无需判断状态码 if(xhr.readyState == 4 ) { isSending = false; console.log(xhr.response); result.innerHTML = xhr.response } } });
4jQuery中的AJAX
4.1GET请求
点击事件get请求方法的四个参数
$.get('url',{请求参数 },回调函数(function(data){ },'json') //获取发起请求的按钮 $('button').eq(0).click(function() { $.get('http://127.0.0.1:8000/jquery-server',{a:100, b:200},function(data){ console.log(data); },'json') });
4.2POST请求
点击事件post请求方法的四个参数
$.get('api',{传递参数},回调函数(function(data){ })//此处不加json获取的是字符串 //获取发起请求的按钮 $('button').eq(1).click(function() { $.post('http://127.0.0.1:8000/jquery-server',{a:100, b:200},function(data){ console.log(data);//data是一个对象 }) });
4.3通用方法AJAX请求
基本类型有四种,url, data, type, success
response.*send*(JSON.*stringify*(data));
若想要得到响应结果为字符串类型,可设置
$.ajax({//内部是一个对象,个人感觉此种用法更方便些 url:'',//路径 data:{},//参数对象 type:'',//请求类型,get或post success:function(data){}//成功回调方法 //其他参数 error:function(data){} //失败回调方法 timeout:2000 //超时处理 dataType: 'json'//响应体结果,json }) $('button').eq(2).click(function() { $.ajax({ //url url:'http://127.0.0.1:8000/jquery-server', //请求参数 data: {a:100,b:200}, //请求类型 type: 'POST/GET', //成功的回调 success: function(data) { console.log(data); } }) });
5.AXIOS发送Ajax请求
axio是目前前端最热门的Ajax工具库,使用频率非常高,也是vue和react的推荐ajax工具。
//安装axios npm install axios --save
5.1axios发送GET请求
这里有两种方法展示:这里采用配置baseURLd的方法:axio.default.baseURL = 'http://127.0.0.1:8000';
5.1.1第一种方法写法
axio.get('/query?name=tom').then(function() { console.log(response); }).catch(function(error) { //异常处理 console.log("出错了!"); })
5.1.2第二种方法写法
axio.get('/query',{ params: { name: 'tom' } }).then(function(){ console.log(response); }).catch(function(error) { //异常处理 console.log("出错了!"); })
5.2axios发送POST请求
axio.post('url',{ //请求体 username: 'admin', password: 'admin' }, //其他配置 { params: { id:200, vip: 100 }, //请求头参数 headers: { height:100, weight: 100 } }).then(function(response) { console.log(response); }).catch(function(error) { console.log(error); })
5.3axios函数发送Ajax请求
axio({ method: 'get', baseURL:'http:127.0.0.1:8000/', url: '/query', data: { name: 'tom' } }).then(function(){ console.log(response); }).catch(function(error) { //异常处理 console.log("出错了!"); })
6.fetch函数发送AJAX请求
btn.onclik = function() { fetch('URL',{ method: 'POST/GET',//请求方法 headers: { name: 'atguiigu' },//请求头 body: 'username=admin&password=admin' //请求体,为body属性而非data }).then(response => { return respon.json(); }).then(response => { console.log(response); }) }
7.跨域
7.1 同源策略
浏览器的一种安全策略
同源:协议、域名、端口号 必须完全相同,违背通关策略就是跨域,Ajax默认满足同源策略。
7.2如何解决跨域问题
7.2.1 JSONP(不推荐)
JSON with padding ,是一个非官方的跨域解决方案,仅支持get请求。
工作方式:借助一些本身跨域的标签。例如img
当正常的请求一个JSON数据时,服务端返回的是一串JSON类型的数据,而使用JSONP模式来请求数据的时候,服务端返回的是一段可执行的JS代码。
JSONP跨域原理:使用动态加载script的src,因此只能把参数通过url的方式传递,也因此请求类型只能是‘get’。
jquey跨域解决方法:
//前端代码 $.getJSON('url?callback=?',function(data) { console.log(data);//数据处理 $('#result').html(` 名称:${data.name}, 校区:${data.city} ) }) //路由规则 app.all('jquery-jsonp-server',(request,response)=>{ let str = JSON.stringfy(data); let cb = request.query.callback; //返回结果 response.end(`${cb}(${str})`); })
7.2.2CORS
Cross-Origin Resource Sharing(跨域资源共享)。是官方的解决方案,特点是不需要在客户端在任何操作,完全在服务器中进行处理,支持get和post请求。
工作方式:通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应就会对响应放行。
CORS的使用:主要是服务器端的设置。
//设置响应头 response.setHeader("Access-Control-Allow-Origin","*"); response.send("hello cors");