axios && fetch
是在框架中使用数据请求
回顾
Ajax封装
- GET
function $get(url, data) {
if (typeof data === 'object') {
url += "?time=" + Date.now();
for (var i in data) {
url += "&" + i + "=" + data[i];
}
}
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(xhr.responseText);
}
setTimeout(() => {
reject(new Error('连接超时'));
}, 2000);
}
});
}
$get('./test.txt', {
"username": "zhansgan"
}).then(function(data) {
console.log(data);
}).catch(function(err) {
console.error(err);
})
- POST
function $post(url, data) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open('post', url, true);
xhr.setRequestHeader('Content-type', 'application/json;charset=utf-8');
if (typeof data === 'object') {
data = JSON.stringify(data);
xhr.send(data);
} else {
xhr.send();
}
xhr.onreadystatechange = function() {
if (xhr.status == 200 && xhr.readyState == 4) {
resolve(xhr.responseText);
}
setTimeout(() => {
reject(new Error('连接超时'));
}, 2000);
}
})
}
$post('lib/hasname.php', {
"username": "zhangsan"
}).then(function(data) {
console.log(data);
}).catch(function(err) {
console.error(err);
})
jQuery【 .get .post .ajax .load 】
- .get
jQuery.get(url, [data], [callback], [type])
- .post
jQuery.post(url, [data], [callback], [type])
- .load
load(url, [data], [callback])
- ajax
$.ajax({
type: "post", // 请求方式
url: "",// 请求地址
data: {
'username': 'zhangsan'// 发送的数据
},
dataType: "json",
beforeSend: function(xhr) {
// beforeSend 发送请求之前执行
console.log(1);
},
dataFilter: function(res) {
// dataFilter 请求成功后执行
// 此回调函数 用于对数据的预处理
// 然后将处理后的 结果 传递给 success
console.log(res);
console.log('dataFilter');
return res;
},
success: function(data) {
// success 成功后执行
// DOM操作
console.log(data);
console.log('success');
},
error: function(xhr) { //失败的回调函数
// console.log(xhr);
// console.log('失败');
if (xhr.status == 404) {
location.href = '';// 请求失败页面
}
},
complete: function(xhr) {
// 无论请求成功还是失败 都会执行
console.log(xhr);
}
});
框架中的数据请求
axios
1. 第三方封装库
2. https://www.npmjs.com/package/axios
3. 特点:
1. 它在浏览器中创建的是浏览器对象
2. 它底层是用Node.js中的http模块实现的
3. 支持Promise
4. 可以拦截请求和响应
- 功能:loading加载效果、登录拦截
5. 转换请求和响应数据
6. 自动转换为JSON数据
7. 客户端支持防止XSRF
8. axios会自动封装数据
4. 使用:
- Mock模拟数据的请求
- 要求:必须和后端沟通好返回数据的字段
- mock.js生成
- mock 目录
- Easy Mock
- jsonplaceholder
- 线上的 http://jsonplaceholder.typicode.com/
- 拷贝线上相似数据
- copy response
- 后端接口的请求
- https://www.showdoc.cc/ 这是一个后端渲染模板
- post请求必须先设置请求头
5. Vue中可以统一对axios进行挂载
- `Vue.prototype.$http = axios`
6. 代码
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<body>
<div id="app">
<button @click ='get'> get </button>
<button @click = "post"> post </button>
</div>
</body>
<script src="../../lib/vue.js"></script>
<script>
// const DEV_BACK_URL / BASE_URL = 后端接口地址
const BACK_URL = 'http://localhost:5000'
const BASIC_URL = 'http://localhost'
axios.defaults.baseURL = BACK_URL;//后端接口地址
/* 统一设置post请求头 */
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
new Vue({
el: '#app',
methods: {
get () {
// axios.get( url, 配置项 ).then().catch()
A: 无参数
axios.get(url).then(res=>console.log(res).catch(error=>conosle.log(error))
B: 有参数
axios({
url: 'http://xxx',
method: 'GET',//默认就是get请求,这个可以不写
params: { // get请求携带参数
key: value
}
}).then( res => {
console.log( res )
}).catch( err => console.log( err ))
},
post () {
// axios.post(url,config).then().catch()
// 注意: axios中post请求如果你直接使用npmjs.com官网文档,会有坑
// 解决步骤:
// 1. 先设置请求头
// 2. 实例化 URLSearchParams的构造器函数得到params对象
// 3. 使用params对象身上的append方法进行数据的传参
const params = new URLSearchParams() // 得到参数携带对象
// params.append(key,value)
params.append( 'a','1' )
params.append( 'b','2' )
axios({
url: `${ BASIC_URL }/post.php`,
method: 'POST',
data: params, // post请求携带参数的配置项
// withCredentials: true,
}).then( res => console.log( res ))
.catch( error => {if( error ){throw error}})
}
}
})
</script>
</html>
fetch
fetch( url, config ).then().then().catch()
1. get
const BASE_URL = 'http://localhost'
methods: {
get () {
fetch('${ BASE_URL }/get.php?a=1&b=2') // get请求参数是连接在url上
.then(data => data.text()) // 数据格式化 data.json() data.blob()
.then(res => {
console.log( res )
})
.catch(error => {
if( error ){
throw error
}
}
}
}
注意事项:
A: fetch 的 get 请求的参数是直接连接在url上的, 我们可以使用Node.js提供的url或是qureystring模块来将
Object --> String
B: fetch 的请求返回的是Promise对象,所以我们可以使用.then().catch(),但是要记住.then()至少要写两个, 第一个then是用来格式化数据的,第二个then是可以拿到格式化后的数据
格式化处理方式有
fetch('./data.json')
.then(res=>{
res.json() //res.text() res.blob() '二进制'
})
.then( data => console.log(data))
.catch( error => console.log( error ))
2. post
const BASE_URL = 'http://localhost'
methods: {
post () {
fetch(`${ BASE_URL }/post.php`,{
method: 'POST',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式为表单提交
}),
body: new URLSearchParams([["a", 1],["b", 2]]).toString()
}).then( data => data.text() )
.then( res => {
this.sum = res
})
.catch( err => console.log( err ))
}
}
封装axios
function request ({
url,
method = 'get' || 'GET',
headers,
params,
data,
baseURL,
auth,
withCredentials = false
}) {
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
// axios.defaults.headers.token = 'sdfsdfs'
axios.defaults.baseURL = baseURL
return new Promise(function ( resolve,reject ) {
console.log('method',method)
switch ( method ) {
case 'get' || 'GET':
axios({
url,
params,
}).then( res => resolve( res ))
.catch( err => reject( err ))
break;
case 'POST':
console.log('post - p')
const p = new URLSearchParams()
// data {a:1,b:2}
if ( data ) {//data存在,那么我们才遍历,不存在,那么我们不遍历
for( let key in data ) {
p.append( key, data[ key ] )
}
}
axios({
url,
data: p,
method,
auth,//针对登录做判断,判断这个用户是普通用户还是超级管理员
withCredentials//这个请求是否具有跨源的凭证
}).then( res => resolve( res ))
.catch( err => reject( err ))
break;
case 'PUT':
axios({
url,
params,
method
}).then( res => resolve( res ))
.catch( err => reject( err ))
break;
case 'DELETE':
axios({
url,
params,
method
}).then( res => resolve( res ))
.catch( err => reject( err ))
break;
default:
break;
}
})
}
调用
new Vue({
el: '#app',
methods: {
async post () {
console.log('post')
const result = await request({
url: '/post.php',
baseURL: 'http://localhost',
method: 'POST',
data: {
a: 1,
b: 2
}
})
console.log( result )
}
}
})
区别
1. fetch vs axios
- axios 对已获得的数据进行了一层封装 XSRF
- axios底层自动对数据进行了格式化
- fetch并没有进行封装,拿到就是格式化后的数据
- fetch进行了多一层的格式化
- res.json()
- res.blob() 格式化二进制
- res.text()
2. 原生js提供了两种数据请求方式
- ajax
- fetch
- ajax vs fetch
- ajax需要封装的, fetch不需要
- ajax不太符合MV* 开发方式,fetch可以认为是js为了MV*方式做的量身打造
- fetch也是Promise
3. vue-resource
- Vue1.0数据请求我们使用的是一个第三方的封装库,这个封装库叫做 vue-resource
- vue-resource现在已经淘汰了,它的作者也推荐我们使用axios
- vue-resource使用形式和axios一样的
- this.$http.get
- this.$http.post
- this.$http({})
- vue-resource有jsonp方法,而axios是没有的
- Vue2.0
- axios [ 可以说是目前最好的数据请求的封装库 ]
- fetch
npx
它是npm 5.2 + 版本新增的命令,使用它可以让我们避免全局安装某一个脚手架,省了内存空间