------------------------前端小白,仅用作自我总结,有问题感谢指出------------------------
一、ajax
1. ajax概念
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
2. ajax跨域
2.1 跨域
浏览器不能执行其他网站的脚本,从一个域名的网页去请求另一个域名的资源时。域名、端口、协议任一不同,都是跨域。跨域是由浏览器的同源策略造成的,是浏览器施加的安全限制。
2.2 跨域解决办法
1.运维同学在服务器做设置
比如:在淘宝的服务器上设置:京东的域名在安全域名的白名单中。
2.前端开启Proxy本地代理
本地的ajax请求先请求到本地同域的服务器中,本地服务器中转请求到跨域服务器,ajax返回的数据也是先返回到本地服务器,由本地服务器再返回到浏览器端。
跨域的问题只只出现浏览器发送请求,服务器发送请求没有跨域问题。
devServer: {
proxy: {
'/api': {
target: 'http://cf-pc-dev.com:7777',
changeOrigin: true,
pathRewrite: {
'^/api': '',
},
},
},
},
对/api/users的请求会将请求代理到http://cf-pc-dev.com
changeOrigin 选项用于修改请求头中的 Host 字段,将其设置为目标URL的主机名
pathRewrite 选项用于重写请求路径,将 /api 去掉
3.jsonp的形式
浏览器端有一个函数名字叫aa,ajax返回的数据我们获取不到但是却可以操作(执行)。 浏览器如果返回123我们获取不到。 但是如果浏览器返回 aa()本地是可以正常执行的。 如果服务器返回 aa(123),也是可以执行的,结果是调用了本地的函数aa,此时如果函数能执行,那么123作为函数的参数被我们获取了。 这种形式就叫做jsonp,要完成这样的工作, 首先我们在发送请求时,需要告诉跨域的服务器,接收参数的函数名称是什么。 xhr.open('get','http://127.0.0.1/a.jsp?callback=aa') 其次,服务器的代码必须经过修改,能够将参数用名称包裹。
JSONP 只支持get请求、不支持post请求
3. 原生ajax
实现过程:
- 创建
XMLHttpRequest对象 - 通过
open()方法与服务器建立连接 - 通过
send()方法发送数据给服务端 - 通过
onreadystatechange事件监听服务器端的通信状态 - 接受服务端向客户端响应的数据结果
// ajax传输的是文本且编码是utf-8编码
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log(xhr.responseText)
} else {
alert('哎呀,服务器睡着啦');
}
}
}
xhr.open(method, url, true); // 创建HTTP请求,method请求类型,url地址,true表示异步
xhr.setRequestHeader(name, value); // name请求头部名称,value请求头部值
xhr.send(); // 发送数据给服务
readyState4个状态:
0初始状态;1请求已发起;2服务器已回应;3数据已发送;4得到服务器的最终回应;
所以,onreadystatechange事件在一次请求中,会触发4次,我们只关心是否进入第四次
设置请求头:
设置发送数据的类型
Content-Type 指传输数据类型;
// 发送表单数据
GET方式,会将表单中的数据(键值对)经过urlencode编码后追加到url中。
POST方式,会将表单中的数据经过urlencode编码后放在request body中。
xhr.setRequestHeader('Content-Type', 'Application/x-www-form-urlencoded');
// 普通表单提交以及表单文件上传
xhr.setRequestHeader('Content-Type', 'multipart/form-data');
// 发送纯文本
xhr.setRequestHeader('Content-Type', 'text/plain');
4. ajax封装
const ajax = {
serialize: function (obj) {
/*
遍历对象obj,使用Object.entries方法将对象{a:1,b:2} 变为[['a',1],['b',2]]
使用for of 遍历[['a',1],['b',2]]
最终形成 'a=1&b=2'
*/
let s = [];
for (let item of Object.entries(obj)) {
s.push(item.join('='))
}
s = s.join('&');
return s;
},
get: function (url, data = {}) {
return new Promise((resolve, reject) => {
//创建xhr对象
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.response))
} else {
reject(xhr.status)
}
}
}
let param = this.serialize(data);
param = param ? '?' + param : '';
xhr.open('get', url + param, true);
xhr.setRequestHeader('Content-Type', 'Application/x-www-form-urlencoded');
xhr.send();
})
},
post: function (url, data = {}) {
return new Promise((resolve, reject) => {
//创建xhr对象
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.response))
} else {
reject(xhr.status)
}
}
}
xhr.open('post', url, true);
//设置请求头
xhr.setRequestHeader('Content-Type', 'Application/x-www-form-urlencoded');
xhr.send(this.serialize(data));
})
}
};
ajax.post('http://172.16.13.182/a', { a: 1, b: 2 }).then(function (result) {
console.log(result);
})
二、axios
2.1 定义
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中
2.2 特征
支持浏览器和node.js;返回promise对象;能拦截请求和响应;能转换JSON数据
2.3 接口请求写法
2.3.1 get请求
axios({
url: '请求路径',
method: 'GET',
params: {},
}).then(res => {
console.log(res)
})
axios.get('请求路径', {
params: {
// 参数...
}
}).then(res => {
console.log(res)
})
2.3.2 post请求
axios({
url: '请求路径',
method: 'POST',
data: {},
}).then(res => {
console.log(res)
})
axios.post('请求路径', {
// 参数...
}).then(res => {
console.log(res)
})
2.4 axios拦截器
拦截器会在每次发起ajax请求和得到响应的时候自动触发。
应用场景:token身份验证
拦截器设置:1.建立interceptor.js文件,配置拦截器相关操作;2.在main.js引入
// http request 拦截器
axios.interceptors.request.use(
config => {
let token = sessionStorage.getItem('wti-manager-token');
token = token ? '' + token : '';
config.headers.Authorization = token;
return config;
},
err => {
return Promise.reject(err);
}
);
// http response 拦截器
axios.interceptors.response.use(
response => {
if (response.data.code === 401) {
const elementMessage = Message;
// 首先关掉之前所有的 message
elementMessage.closeAll();
elementMessage({
message: '登陆认证已过期,请重新登陆!',
type: 'warning',
});
Router.push({name: 'Login'});
}
return response.data;
},
error => {
// console.log('reject', error);
// 对响应错误做点什么
window.top.postMessage(
{
message: '您的网络连接失败,请稍后再试',
type: 'warning',
wti_type: 'message'
},
'*'
);
return Promise.reject(error.response.data);
}
);
ajax 与 axios 的根本区别
axios 是基于promise实现的对 ajax 技术的一种封装,两者用法基本一样,个别参数不同,axios 封装了一些更简便的 ajax 操作 axios 是 ajax,但是 ajax 不限于 axios