Vue http请求

      我们在构建应用时通常需要访问一个 API 并展示其数据。做这件事的方式有好几种。这边我将在 firebase 上创建自己的数据库,然后通过 vue-resource、axios 和 fetch 三种方式对数据进行增删改查。让我们了解 vue 是怎样进行 http 请求的。

vue-resource

      vue-resource 是 Vue.js 的一款通过 XMLHttpRequest 或 JSONP 发起请求并处理响应的插件。它能做的是和 ajax 一样,但是比 ajax 的 API 更为简洁。

1.安装

1
npm install vue-resource --save-dev

2.引入并全局使用

main.js

1
2
import VueResource from 'vue-resource
Vue.use(VueResource)

3.post 请求

post(url, [body], [options])

1
2
3
4
this.$http.post("https://vue-blog-62383.firebaseio.com/posts.json",this.blog)
.then(data => {
console.log(data); ////返回Response对象
});

3.get 请求
get(url, [options])

1
2
3
4
5
6
7
8
this.$http
.get("https://vue-blog-62383.firebaseio.com/posts.json")
.then(data => {
return data.json(); //返回Promise对象
})
.then(data => {
console.log(data); //拿到数据库中的数据
});

4.删除对应数据
delete(url, [options])

1
2
3
4
5
6
7
8
this.$http
.delete(
//删除对应数据
"https://vue-blog-62383.firebaseio.com/posts/" + this.id + ".json"
)
.then(res => {
//删除后对应操作
});

5.修改对应数据
put(url, [body], [options])

1
2
3
4
5
6
7
this.$http
.put(
"https://vue-blog-62383.firebaseio.com/posts/" + this.id + ".json",this.blog
) //成功之后
.then(data => {
//修改后对应操作
});

      以上就是使用 vue-resource 实现的增删改查。具体的配置项可以看看官网。vue-resources 目前官网已经不再进行更新维护了。目前官方推荐的是 axios。接下来我们看看 axios 吧。

axios

      axios 是目前主流的 http 请求,是一个基于 promise 的 HTTP 库。也是目前官方推荐的。建议大家多去使用一些主流请求数据的方法。

1.安装

1
npm install axios

2.引入

1
import axios from  ‘axios'

3.post 请求

axios.post(url[, data[, config]])

1
2
3
4
5
6
7
8
axios.post("https://vue-blog-62383.firebaseio.com/posts.json",this.blog)
.then(data => {
//成功
console.log(data);
}).catch(error=>{
//失败
console.log(error);
});

4.get 请求

axios.get(url[, config])

1
2
3
4
5
6
7
axios
.get("https://vue-blog-62383.firebaseio.com/posts.json")
.then(res) => {
console.log(res);
//获取数据
console.log(res.data);
})

console.log(res);

1
2
3
4
5
6
7
8
9
10
{data}: {…}, status: 200, statusText: "OK", headers: {…}, config: {…}, …}
config:{}
data:
authors: "Lucy"
categories: ["vue.js"]
content: "错误原因的内容"
phContent: "请输入博客内容"
phTitle: "请输入博客标题"
title: "错误原因611"
__proto__: Object

      我们把res打印出来,可以看到 res 中的 data 是我们想要拿到的数据。所以我们直接通过res.data的方式拿到数据。注意:这里和 vue-resource 不一样的在于,不需要 res.json()去解析,axios 直接解析出来的就是一个对象

4.删除对应数据

axios.delete(url[, config])

1
2
3
axios.delete("https://vue-blog-62383.firebaseio.com/posts/" + this.id + ".json").then(res => {
//删除后执行方法
});

5.修改对应数据

1
2
3
4
5
6
7
8
9
10
axios
.put(
"https://vue-blog-62383.firebaseio.com/posts/" + this.id + ".json",
this.blog
)
.then(res => {
//获取修改数据
console.log(res.data);
}
);

6.请求配置(官网)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
{
// `url` 是用于请求的服务器 URL
url: '/user',

// `method` 是创建请求时使用的方法
method: 'get', // 默认是 get

// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
baseURL: 'https://some-domain.com/api/',

// `transformRequest` 允许在向服务器发送前,修改请求数据
// 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
// 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
transformRequest: [function (data) {
// 对 data 进行任意转换处理

return data;
}],

// `transformResponse` 在传递给 then/catch 前,允许修改响应数据
transformResponse: [function (data) {
// 对 data 进行任意转换处理

return data;
}],

// `headers` 是即将被发送的自定义请求头
headers: {'X-Requested-With': 'XMLHttpRequest'},

// `params` 是即将与请求一起发送的 URL 参数
// 必须是一个无格式对象(plain object)或 URLSearchParams 对象
params: {
ID: 12345
},

// `paramsSerializer` 是一个负责 `params` 序列化的函数
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
paramsSerializer: function(params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},

// `data` 是作为请求主体被发送的数据
// 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
// 在没有设置 `transformRequest` 时,必须是以下类型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属:FormData, File, Blob
// - Node 专属: Stream
data: {
firstName: 'Fred'
},

// `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
// 如果请求话费了超过 `timeout` 的时间,请求将被中断
timeout: 1000,

// `withCredentials` 表示跨域请求时是否需要使用凭证
withCredentials: false, // 默认的

// `adapter` 允许自定义处理请求,以使测试更轻松
// 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)).
adapter: function (config) {
/* ... */
},

// `auth` 表示应该使用 HTTP 基础验证,并提供凭据
// 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头
auth: {
username: 'janedoe',
password: 's00pers3cret'
},

// `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
responseType: 'json', // 默认的

// `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称
xsrfCookieName: 'XSRF-TOKEN', // default

// `xsrfHeaderName` 是承载 xsrf token 的值的 HTTP 头的名称
xsrfHeaderName: 'X-XSRF-TOKEN', // 默认的

// `onUploadProgress` 允许为上传处理进度事件
onUploadProgress: function (progressEvent) {
// 对原生进度事件的处理
},

// `onDownloadProgress` 允许为下载处理进度事件
onDownloadProgress: function (progressEvent) {
// 对原生进度事件的处理
},

// `maxContentLength` 定义允许的响应内容的最大尺寸
maxContentLength: 2000,

// `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认的
},

// `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目
// 如果设置为0,将不会 follow 任何重定向
maxRedirects: 5, // 默认的

// `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项:
// `keepAlive` 默认没有启用
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),

// 'proxy' 定义代理服务器的主机名称和端口
// `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据
// 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。
proxy: {
host: '127.0.0.1',
port: 9000,
auth: : {
username: 'mikeymike',
password: 'rapunz3l'
}
},

// `cancelToken` 指定用于取消请求的 cancel token
// (查看后面的 Cancellation 这节了解更多)
cancelToken: new CancelToken(function (cancel) {
})
}

7.axios 全局配置

main.js

1
2
3
4
5
6
7
8
9
10
//在实际开发过程中,基本前面的域名是一样的,可以通过配置baseURL去简化代码
// 配置axios请求的地址
axios.defaults.baseURL = 'https://vue-blog-62383.firebaseio.com'
//在登录场景的时候后台人员通常会要求有一个token的值,只有token验证成功了,才能登录
//设置请求头为 Authorization
axios.defaults.headers.common('Authorization') = 'Token'
//设置post请求头
axios.defaults.headers.post['Content-Type'] = 'application/urlencode';
//设置get请求头
axios.defaults.headers.get['Accepts'] = 'application/json'

无配置全局 baseURL

1
2
3
axios.get("https://vue-blog-62383.firebaseio.com/posts/" + this.id + ".json").then(res => {
console.log(res.data);
});

配置全局 baseURL 后

1
2
3
axios.get("/posts/" + this.id + ".json").then(res => {
console.log(res.data);
});

8.抽离 axios 到单独文件

比如 axios-auto.js

1
2
3
4
5
6
7
8
9
10
11
import axios from 'axios'
// 创建实例时设置配置的默认值
const instance = axios.create({
baseURL: 'https://vue-blog-62383.firebaseio.com'
});
// 在实例已创建后修改默认值
instance.defaults.headers.common('Authorization') = 'Token'
//自定义 axios 实例添加拦截器
instance.interceptors.request.use(function () {});
//暴露出去
export default instance

如果想单独引用 axios.js 里面的配置,则根据路径直接在对应的地方引入

1
import axios from "../axios-auto";

9.拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 添加请求拦截器
const myInterceptor = axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
//移除拦截器
axios.interceptors.request.eject(myInterceptor);

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});

fetch

      Fetch 是 axios 的一个替代方案。使用 Fetch 有很多别的注意事项,这也是为什么官网更推荐我们用 axios 的原因。Fetch 是浏览器提供的原生 AJAX 接口。我们在使用它的时候不需要额外加载一个外部资源。关于 fetch 可以看看我之前的关于异步编程的文章

1.post 请求

1
2
3
4
5
6
7
8
9
10
11
12
13
fetch("https://vue-blog-62383.firebaseio.com/posts.json", {
method: "POST",
headers:{
token:"f0292837363794947"
},
body:JOSN.stringify({id: 1,name: 'Lucy'});
}) .then(result => {
return result.json();
})
.then(data => {
console.log(data);
}
);

2.get 请求

1
2
3
4
5
6
7
8
9
fetch("https://vue-blog-62383.firebaseio.com/posts.json")
.then((res) => res.json())
.then((data) => {
console.log(data);
})
.catch(err => {
console.log(err);
});
});

3.修改

1
2
3
4
5
6
7
8
9
10
11
12
13
fetch("https://vue-blog-62383.firebaseio.com/posts.json", {
method: "PUT",
headers:{
'content-type': 'application/json'
},
body:JOSN.stringify({id: 2,name: 'Lucy'});
}) .then(result => {
return result.json();
})
.then(data => {
console.log(data);
}
);

4.删除

1
2
3
4
5
6
7
8
9
10
11
12
fetch("https://vue-blog-62383.firebaseio.com/posts.json", {
method: "DELETE",
headers:{
token:"f0292837363794947"
},
}) .then(result => {
return result.json();
})
.then(data => {
console.log("删除成功");
}
);

跨域问题

如果看到以下报错,就是因为浏览器的同源策略导致了跨域

1
2
3
4
5
6
7
Access to XMLHttpRequest at 'XXX' from origin 'http://
localhost:8084' has been blocked by CORS policy:
The value of the 'Access-Control-Allow-Origin' header
in the response must not be the wildcard '*' when the
request's credentials mode is 'include'. The credentials
mode of requests initiated by the XMLHttpRequest is
controlled by the withCredentials attribute.

Vue Cli2+解决

config/index.js,在 proxyTable 中添写如下代码

1
2
3
4
5
6
7
8
9
10
11
 //跨域请求设置,跨域完整地址:http://f.apiplus.cn/bj11x5.json
proxyTable: {
//使用"/apis"来代替"http://f.apiplus.cn ",一定要有http,如果是对应的ip,也需要有http
'/apis': {
target: 'http://f.apiplus.cn/', //接口域名
changeOrigin: true, //是否跨域
pathRewrite: {
'^/apis': '' //路径重写
}
}
},

Vue Cli3+解决

根目录创建 vue.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
module.exports = {
devServer: {
proxy: {
'/apis': {
target: 'http://f.apiplus.cn/', //接口域名
changeOrigin: true, //是否跨域
pathRewrite: {
'^/apis': '' //路径重写
}
}
},
}
}

相应跨域请求

1
2
3
4
5
6
7
8
9
//apis相当于http://f.apiplus.cn
fetch("/apis/bj11x5.json", {
method: "post"
}) .then(result => {
return result.json();
})
.then(data => {
console.log(data);
});

通过以上代码实现的具体事例可以看这里

Copyright ©2019 guowj All Rights Reserved.

访客数 : | 访问量 :