服务端跨域资源共享问题
在客户端请求服务端接口的时候,可能会跨域,提示被 CORS 阻止了。这个时候服务端需要在做出响应的时候在头部添加一个 ‘Access-Control-Allow-Origin’ ,用这个头部去设置服务端允许访问的域。
在 node 服务端,安装 cors 这个包,然后在 index 文件中使用。
1 2 3 4 5 6 7 8 9 10
| import cors from 'cors'; /** * 跨域资源共享 */ app.use( cors({ origin: "*", //允许所有域访问 exposedHeaders: "X-Total-Count", //设置允许的自定义的头部 }) );
|
安装与使用 http 客户端请求服务端接口(axios)
安装 axios: npm install axios
使用的时候:
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
| <template> <h3>{{ name }}</h3> <div v-for="post in posts" :key="post.id"> {{ post.title }} - <small>{{ post.user.name }}</small> </div> </template>
<script> import axios from 'axios'; export default { data() { return { name: '你好啊', posts: [], }; }, created() { axios.get('http://localhost:3000/posts').then(response => { console.log(response); this.posts = response.data; }).catch(error=>{ console.log(error.message) console.log(error.response) }); }, }; </script>
|
处理在 Vue 应用里使用 axios 发送请求时发生的错误
处理错误写在 catch 区块中:
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
| <template> <h3>{{ name }}</h3> <div> {{ errorMessage }} </div> <div v-for="post in posts" :key="post.id"> {{ post.title }} - <small>{{ post.user.name }}</small> </div> </template>
<script> import axios from 'axios'; export default { data() { return { name: '你好啊', posts: [], errorMessage: '', }; }, created() { axios .get('http://localhost:3000/posts1') .then(response => { console.log(response); this.posts = response.data; }) .catch(error => { console.log(error.message); console.log(error.response); this.errorMessage = error.message; }); }, }; </script>
|
使用 async、await 处理 axios 请求
改造一下请求方式:
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
| <template> <h3>{{ name }}</h3> <div> {{ errorMessage }} </div> <div v-for="post in posts" :key="post.id"> {{ post.title }} - <small>{{ post.user.name }}</small> </div> </template>
<script> import axios from 'axios'; export default { data() { return { name: '你好啊', posts: [], errorMessage: '', }; }, async created() { try { const response = await axios.get('http://localhost:3000/posts'); this.posts = response.data; } catch (error) { this.message = error.message; } }, }; </script>
|
axios 请求的配置
在 axios 里可以添加请求的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| async created() { try { const response = await axios({ method: 'get', //请求方法 url: '/posts', //接口地址 baseURL: 'http://localhost:3000', //请求基础地址 headers: { 'X-Custom': 'hello~', }, }); this.posts = response.data; } catch (error) { this.message = error.message; } },
|
axios 默认的配置
修改默认的配置,每次请求就不用带基本地址了。新建个 app.service.ts:
1 2 3 4 5
| import axios from 'axios';
axios.defaults.baseURL = 'http://localhost:3000';
export { axios };
|
使用的时候:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <script> import { axios } from '@/app/app.service'; //导入 export default { data() { return { name: '你好啊', posts: [], errorMessage: '', }; }, async created() { try { const response = await axios.get('/posts'); //不用带基本地址了 console.log(axios.defaults); //打印axios的默认配置 this.posts = response.data; } catch (error) { this.message = error.message; } }, }; </script>
|
axios 的请求与响应的拦截器
在 axios 发送请求前和收到响应后,我们可以去设置一些拦截器,可以拦截请求和响应。你可以在这些拦截器里,提前处理一下请求和响应。拦截器的设置:
app.service.ts 中:
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
| import axios from 'axios';
axios.defaults.baseURL = 'http://localhost:3000';
/** * 请求拦截器 */
axios.interceptors.request.use( config => { //正常请求用的回调,支持一个config参数,值是axios用的请求的配置 console.log('axios请求拦截器', config); return config; }, error => { return Promise.reject(error); }, );
/** * 响应拦截器 */ axios.interceptors.response.use( response => { console.log('axios响应拦截器', response); return response; }, error => { return Promise.reject(error); }, );
export { axios };
|
在请求的时候和响应的时候 ,会看到控制台打印出了相关的东西。
创建与使用 axios 实例
app.service.ts:
1 2 3 4 5 6
| /** * axios实例 */ const apiHttpClient = axios.create({ baseURL: 'http://localhost:3000', });
|
使用和正常 axios 一样:
1 2 3 4 5 6 7 8 9
| async created() { try { const response = await apiHttpClient.get('/posts'); // console.log(axios.defaults); this.posts = response.data; } catch (error) { this.message = error.message; } },
|
发送 post 类型的 http 请求
1 2 3 4 5 6 7 8 9
| //用户登录 try { const response = await apiHttpClient.post('/login', this.user); this.token = response.token;
console.log(response.data); } catch (error) { this.errorMessage = error.message; }
|
在请求里配置头部数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| async createPost() { try { const response = await apiHttpClient.post( '/posts', { title: this.title, },
//post的第三个参数是配置项,可以在里面配置headers { headers: { Authorization: `Bearer ${this.token}`, }, }, ); console.log(response.data);
this.title = '';
this.getPosts(); } catch (error) { this.errorMessage = error.message; } },
|
发送 patch/put 类型的 http 请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| async updatePost(event, postId) { try { await apiHttpClient.patch( `/posts/${postId}`, { title: event.target.value, }, { headers: { Authorization: `Bearer ${this.token}`, }, }, ); this.getPosts(); } catch (error) { this.errorMessage = error.message; } },
|
发送 delete 类型的 http 请求
1 2 3 4 5 6 7 8 9 10 11 12
| async deletePost(postId) { try { await apiHttpClient.delete(`/posts/${postId}`, { headers: { Authorization: `Bearer ${this.token}`, }, }); this.getPosts(); } catch (error) { this.errorMessage = error.message; } },
|