AJAX
1.原生AJAX
1.1AJAX简介
AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。
通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。
AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
1.2XML简介
XML 可扩展标记语言。
XML 被设计用来传输和存储数据。
XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签,
比如说我有一个学生数据: name = "孙悟空" ; age = 18 ; gender = "男" ; 用 XML 表示: <student> <name>孙悟空</name> <age>18</age> <gender>男</gender> </student>
1.3AJAX的特点
1.3.1AJAX的优点
- 可以无需刷新页面而与服务器端进行通信
- 允许你根据用户事件来更新部分页面内容
1.3.2AJAX的缺点
-
没有浏览历史,不能回退
-
存在跨域问题(同源)
-
SEO 不友好
1.3.3AJAX的一般使用场景
搜索栏,(搜索栏输入一个值,在下面出现一系列值)
注册页面,
淘宝页面(用户点击,向服务器发请求,返回请求,出现效果)等网页
1.3.4使AJAX技术得到实现的技术
-
XMLHttpRequest(XHR)对象
-
axios
-
Fetch技术
-
JSONP
1.3.5需要了解的其他知识
1.HTTP协议,以及如何在游览器中怎么查看里面的一些属性
-
用户事件
-
SEO
4.关于POST和GET的区别(POST方式的请求体可以为空,GET方式的请求体为空)
5.关于怎么解决跨域的问题
2.使用XHR来实现AJAX
2.1前提知识
2.1.1XHR的readyState属性
有5个值,用于表示当前处在请求、响应过程的那个阶段
0 | 未初始化。尚未调用open()方法 |
---|---|
1 | 已打开(Open) 已调用open()方法,尚未调用send()fangfa |
2 | 已发送(Sent)。已调用send()方法,尚未收到响应 |
3 | 接收中(Receiving).已经收到部分响应 |
4 | 完成(Complete)已经收到所有的响应,可以使用 |
2.1.2常见的状态响应码(status)
1xx:指示信息--表示请求已接收,继续处理
2xx:成功--表示请求已被成功接收、理解、接受
3xx:重定向--信息不完整需要进一步补充
4xx:客户端错误--请求有语法错误或请求无法实现
5xx:服务器端错误--服务器未能实现合法的请求
200 交易成功
400 错误请求,如语法错误
403 禁止访问
404 没有发现文件、查询或URL
500 内部服务器错误
详情了解可参考状态响应码
2.1.3利用express搭建一个简单的服务器
2.2开始实现
2.2.1搭建一个简单的服务器
const express = require('express'); const app = express(); app.get('/server', (request, response) => { //设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin', '*'); //设置响应体 response.send('HELLO AJAX - 2'); }); //4. 监听端口启动服务 app.listen(8000, () => { console.log("服务已经启动, 8000 端口监听中...."); }) 开启8000端口的服务器,用与客户端向其发送请求
2.2.2GET方式
<style> #result{ width:200px; height:100px; border:solid 1px #90b; } </style> <button>点击发送请求</button> <div id="result"></div>
<script>
//获取button元素
const btn = document.getElementsByTagName('button')[0];
const result = document.getElementById("result");
//绑定事件
btn.onclick = function(){
//1. 创建对象
const xhr = new XMLHttpRequest();
//2. 初始化 设置请求方法和 url
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
//3. 发送
xhr.send();
//4. 事件绑定 处理服务端返回的结果
// on when 当....时候
// readystate 是 xhr 对象中的属性, 表示状态 0 1 2 3 4
// 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);//响应体
//设置 result 的文本
result.innerHTML = xhr.response;
}else{
console.log("it was error")
}
当点击按钮时(先开启服务器代码,进入到服务器代码的目录中使用 node -xxx.js)
2.2.3POST方式
与前面代码相似:
xhr.open('POST', 'http://127.0.0.1:8000/server'); //设置请求头 xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.setRequestHeader('name','atguigu'); //3. 发送 xhr.send('a=100&b=200&c=300');
POST方式可携带参数,server.js中修改
response.send('HELLO AJAX POST')
2.2.4 你也可以设置服务器端发送代码的数据形式!g
const data = { name: 'atguigu' }; //对对象进行字符串转换 let str = JSON.stringify(data); //设置响应体 response.send(str);
1. 手动对数据转化 let data = JSON.parse(xhr.response) console.log(data); result.innerHTML = data.name; 2. 自动转换 //设置响应体数据的类型 xhr.responseType = 'json';(在xhr.onreadystatechange之前) console.log(xhr.response); result.innerHTML = xhr.response.name;
2.2.5解决IE缓存的问题
IE缓存问题:就是在客户端向服务器发送请求,第一次请求正常,第二次
显示的结果为第一次的结果。这是因为IE走的是缓存。
解决方法:
可在请求的url后面添加Date.now()(时间戳)
eg:xhr.open("GET",'http://127.0.0.1:8000/ie?t='+Date.now());
2.2.6关于超时和网络异常时数据显示的效果
setTimeout(() => { //设置响应体 response.send('延时响应'); }, 3000) 服务器端修改
客户端修改
//超时设置 2s 设置 xhr.timeout = 2000; //超时回调 xhr.ontimeout = function(){ alert("网络异常, 请稍后重试!!"); } /网络异常回调 xhr.onerror = function(){ alert("你的网络似乎出了一些问题!"); }
此时弹出弹框显示-------"网络异常, 请稍后重试!!
当你设置网络为断网时弹框显示--------“你的网络似乎出了一些问题!”
在network中下的Oline选项选择offline(设置断网)
3.使用 jQuery方式实现
jQuery有多种实现AJAX的属性
具体可参考jQuery官网jQuery
3.1 jQuery的GET方法
服务器端代码(修改)前面的内容还是要的
const data = { name:'尚硅谷'}; response.send(JSON.stringify(data))
客户端代码
$.get('http://127.0.0.1:8000/jquery-server', { a:100, b:200}, function(data){ console.log(data); },'json'); 数据输出形式为json形式
3.2 jQuery的POST方法
$.post('http://127.0.0.1:8000/jquery-server', { a:100, b:200}, function(data){ console.log(data); });
3.3 jQuery的通用方法
$.ajax({ //url url: 'http://127.0.0.1:8000/jquery-server', //参数 data: { a:100, b:200}, //请求类型 type: 'GET', //响应体结果 dataType: 'json', //成功的回调 success: function(data){ console.log(data); }, //超时时间 timeout: 2000, //失败的回调 error: function(){ console.log('出错啦!!'); }, //头信息 headers: { c:300, d:400 } });
因为在服务器设置了response.send('延时响应'); }, 3000)
而在通用方法中timeout: 2000,
4.axios方式
4.1在项目中添加axios
$ npm install axios
需要注意的是axios方式得到的数据是Promise对象
4.2axios的GET方式
可以设置
axios.defaults.baseURL = ‘http://127.0.0.1:8000’;
下面就不必写那么长的url
axios.get(url[, config])
axios.get('/axios-server', { //url 参数 params: { id: 100, vip: 7 }, //请求头信息 headers: { name: 'atguigu', age: 20 } }).then(value => { console.log(value); }); }
4.3axios的POST方式
axios.post(url[, data[, config]])
axios.post('/axios-server', { username: 'admin', password: 'admin' }, { //url params: { id: 200, vip: 9 }, //请求头参数 headers: { height: 180, weight: 180, } });
4.4axios的通用方式
axios(url[, config])或者axios(config)
axios({ //请求方法 method : 'POST', //url url: '/axios-server', //url参数 params: { vip:10, level:30 }, //头信息 headers: { a:100, b:200 }, //请求体参数 data: { username: 'admin', password: 'admin' } }).then(response=>{ //响应状态码 console.log(response.status); //响应状态字符串 console.log(response.statusText); //响应头信息 console.log(response.headers); //响应体 console.log(response.data); })
5.Fetch方式
fetch('http://127.0.0.1:8000/fetch-server?vip=10', { //请求方法 method: 'POST', //请求头 headers: { name:'atguigu' }, //请求体 body: 'username=admin&password=admin' }).then(response => { // return response.text(); return response.json(); }).then(response=>{ console.log(response); });
通过fetch方式得到的数据也是Promise对象
6.跨域
6.1同源策略
同源策略(Same-Origin Policy)最早由 Netscape 公司提出,是浏览器的一种安全策略
同源: 协议、域名、端口号 必须完全相同。
违背同源策略就是跨域。
6.2如何解决跨域
此时server.js改变
const express = require('express'); const app = express(); app.get('/home', (request, response)=>{ //响应一个页面 response.sendFile(__dirname + '/index.html'); }); app.get('/data', (request, response)=>{ response.send('用户数据'); }); app.listen(9000, ()=>{ console.log("服务已经启动..."); });
6.2.1 jsonp方式
- JSONP 是什么
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明
才智开发出来,只支持 get 请求。 - JSONP 怎么工作的?
在网页有一些标签天生具有跨域能力,比如:img link iframe script。
JSONP 就是利用 script 标签的跨域能力来发送请求的。
JSONP 的使用
//1.动态的创建一个 script 标签 var script = document.createElement("script"); //2.设置 script 的 src,设置回调函数 script.src = "http://localhost:3000/testAJAX?callback=abc"; function abc(data) { alert(data.name); }; //3.将 script 添加到 body 中 document.body.appendChild(script); //4.服务器中路由的处理 router.get("/testAJAX" , function (req , res) { console.log("收到请求"); var callback = req.query.callback; var obj = { name:"孙悟空", age:18 } res.send(callback+"("+JSON.stringify(obj)+")"); });
6.2.2 CORS
- CORS 是什么?
CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方
案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持
get 和 post 请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些
源站通过浏览器有权限访问哪些资源 - CORS 怎么工作的?
CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应
以后就会对响应放行。
CORS 的使用
//主要是服务器端的设置: router.get("/testAJAX" , function (req , res) { //通过 res 来设置响应头,来允许跨域请求 //res.set("Access-Control-Allow-Origin","http://127.0.0.1:3000"); res.set("Access-Control-Allow-Origin","*"); res.send("testAJAX 返回的响应"); });