文章目录
- 1 引言
- 1.1 vue-resource
- 1.1.1 jsonp请求原理
- 1.1.2 vue-resource一些配置
- 1.1.3 示例
- 1.1.3.1 get请求
- 1.1.3.2 post请求
- 1.1.3.3 JSONP请求
- 1.2 axios
- 1.2.1 下载引入
- 1.2.2 发起请求
- 1.2.2.1 get请求
- 1.2.2.2 post请求
- 1.2.3 合并请求
- 1.2.4 axios拦截器
- 1.2.4.1 拦截器的设置
1 引言
vuejs
实现数据请求有 vue-resource
和第三方包axios
等
1.1 vue-resource
可以安装插件,早期vue
团队开发的插件,但是停止维护了,作者推荐使用axios
下载依赖
npm i vue-resource
安装依赖
import VueResource from 'vue-resource';
Vue.use(VueResource);
//为来通过this.$http
// Vue是所有势力的对象构造函数
// Vue.protptype.$http -> 实例(this)就可以使用 .$http 比如:this.$http
1.1.1 jsonp请求原理
JSONP
的实现原理:
由于浏览器的安全性限制,不允许AJAX
访问协议不同
、域名不同
、端口号不同
的数据接口,浏览器认为这种访问不安全;
可以通过动态创建script
标签的形式,把script
标签的src
属性,指向数据接口的地址,因为script
标签不存在跨域限制,这种数据获取方式,称作JSONP
(注意:根据JSONP
的实现原理,知晓,JSONP
只支持Get
请求);
具体实现过程:
- 先在客户端定义一个回调方法,预定义对数据的操作;
- 再把这个回调方法的名称,通过
URL
传参的形式,提交到服务器的数据接口; - 服务器数据接口组织好要发送给客户端的数据,再拿着客户端传递过来的回调方法名称,拼接出一个调用这个方法的字符串,发送给客户端去解析执行;
- 客户端拿到服务器返回的字符串之后,当作
Script
脚本去解析执行,这样就能够拿到JSONP
的数据了
1.1.2 vue-resource一些配置
如果通过全局配置了,请求的数据接口根域名,那么在每次单独发起http
请求的时候,请求的 url
路径,应该以相对路径开头,前面不能带 /
,否则 不会启用根路径做拼接;
Vue.http.options.root = 'http://vue.studyit.io/';
需要注意的是如果配置了全局根域名,那么在请求中要使用相对路径,而不是绝对路径
例如:
// 此处访问的url是相对路径,就不能绝对路径
this.$http.get('api/getprodlist').then(result => {
var result = result.body
if (result.status === 0) {
// 成功了
this.list = result.message
} else {
// 失败了
alert('获取数据失败!')
}
});
全局启用emulateJSON
选项,可以使用json
风格传输协议
Vue.http.options.emulateJSON = true;
当浏览器发起options
预检请求时,是当浏览器发现跨域 + application/json
的请求,就会自动发起并且发起的时候携带了一个content-type
的头
此时,可以在全局配置如上的请求emulateJSON
1.1.3 示例
如下是测试的URL
请求资源地址:
get请求地址: http://vue.studyit.io/api/getlunbo
post请求地址:http://vue.studyit.io/api/post
jsonp请求地址:http://vue.studyit.io/api/jsonp
在做如下例子时需要先引入包:vue-resource-1.3.4.js
1.1.3.1 get请求
发送get请求:
getInfo() { // get 方式获取数据
this.$http.get('http://127.0.0.1:8899/api/getlunbo').then(res => {
console.log(res.body);
})
}
1.1.3.2 post请求
发送post请求:post
方法接收三个参数:
- 参数1: 要请求的
URL
地址 - 参数2: 要发送的数据对象
- 参数3: 指定
post
提交的编码类型为application/x-www-form-urlencoded
postInfo() {
var url = 'http://127.0.0.1:8899/api/post';
this.$http.post(url, { name: 'zs' }, { emulateJSON: true }).then(res => {
console.log(res.body);
});
}
1.1.3.3 JSONP请求
发送JSONP请求获取数据:
jsonpInfo() { // JSONP形式从服务器获取数据
var url = 'http://127.0.0.1:8899/api/jsonp';
this.$http.jsonp(url).then(res => {
console.log(res.body);
});
}
1.2 axios
1.2.1 下载引入
axios
(读音:艾克西奥斯),也是用来发起数据请求的一种方式
下载依赖
npm install axios
安装依赖
import Axios from 'axios';
//给vue原型挂载一个对象
Vue.prototype.$axios=Axios;//在以后是通过this.$axios的方式来使用
1.2.2 发起请求
可以在发起请求时做个全局的URL
配置:Axios.defaults.baseURL='http://127.0.0.1:8080/api/'
,这样的话下面请求就只用拼接到url后面的请求就可以了
1.2.2.1 get请求
this.$axios.get(url,options).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
});
options
可以相关设置:
options:{
params:{id:1}//查询字符串,
headers:{ 'content-type':'xxxxx' },
baseURL:''
}
1.2.2.2 post请求
post
请求的时候,如果数据是字符串默认头就是键值对,否则是对象就是application/json
this.$axios.post(url,data,options).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
});
1.2.3 合并请求
axios
合并请求将两个请求合并一起发送,只有一个失败,就算失败,成功只有是全体成功,命令:axios.all([请求1,请求2])
同时需要分发请求: axios.spread(fn)
,fn
:对应参数(res
)和请求的顺序一致
例如:
this.$axios.all([
this.$axios.post(url,data,options),
this.$axios.get(url,options)
]).then(this.$axios.spread(fn)).catch(err=>{
console.log(err);
});
function fn(res1,res2){
console.log(res1);
console.log(res2);
}
1.2.4 axios拦截器
axios
拦截器就是在每一次请求与响应中过滤一些信息
拦截器使用API
是axios.interceptors.request.use(fn)
在请求之前function(config){ config.headers = { xxx }}
config
相当于options
对象
注意:
- 默认设置(
defaults
)是范围广,但是优先级小; - 单个请求的设置范围小,但是优先级中;
- 拦截器是范围广,但是优先级大
1.2.4.1 拦截器的设置
import Mint from 'mint-ui';
Vue.use(Mint);
//拦截request请求
Axios.interceptors.request.use(function(config){
//修改一些请求头信息
config.headers.accept='interceptors';
//添加loading图标
Mint.Indicator.open();
return config;//最后要返回config
});
//拦截response响应
Axios.interceptors.response.use(function(data){
Mint.Indicator.close();
return data;//最后要返回data
});