Vue 中 axios 的使用和跨域问题的解决
一、内容:
1.Axios
(1)Axios是一个 HTTP库,类似于 jQuery 的 ajax,用于http请求。axios 并不是 vue 插件,所以不能使用 Vue.use()。
(2)它既可以应用于浏览器端,也可以应用于node.js编写的服务端。
(3)Axios具有以下特性:
1)基于 promise,支持Promise API。
2)拦截请求与响应,比如:在请求前添加授权和响应前做一些事情。
3)转换请求数据和响应数据,比如:进行请求加密或者响应数据加密。
4)取消请求。
5)自动转换JSON数据。
6)客户端支持防御XSRF(跨站点请求伪造)。
2.Promise
(1)从发起请求到接收响应时执行回调,是一个异步过程;Promise API 是一种异步编程的解决方案,可以帮助管理异步操作,使得代码更易于理解和维护。
(2)Promise 的基本流程包括以下几个步骤:
1)创建一个新的 Promise 对象,并传入一个执行器函数作为参数。执行器函数接受两个参数:resolve 和 reject,分别用于在异步操作成功或失败时改变 Promise 的状态。
2)在执行器函数中执行异步操作,如果操作成功,则调用 resolve 函数,将 Promise 状态变为已解决,并将操作结果作为参数传递出去;如果操作失败,则调用 reject 函数,将 Promise 状态变为已拒绝,并将错误信息作为参数传递出去。
3)通过调用 Promise 对象的 then 方法或 catch 方法来处理异步操作的结果。then 方法用于处理操作成功的情况,catch 方法用于处理操作失败的情况。
二、安装:
执行命令:cd xxxx(项目目录)
执行命令:npm install axios
三、创建 network
在 src 目录下创建目录 network,在目录 network 下创建三个文件 http.js、api.js、request.js:
(1)request.js,引入 axios,创建 axios 实例 request,配置并暴露 request:
import axios from "axios"; const request = axios.create({ baseURL: '', timeout: 5000 }); //判断本地是否存储了 token, 如果有,则通过 Authorization,将 token 发给服务器,用于认证 request.interceptors.request.use(config=>{ let token = localStorage.getItem('token'); if(token){ const bToken = 'Bearer '+ token; config.headers.Authorization = bToken; } return config; }); request.interceptors.response.use(response=>{ return response; }, error=>{ return error; }); export default request;
(2)http.js,引入 request 之后,创建 http 对象,封装对 request 的调用:
import request from "./request"; const http ={ get(url, params, headers){ const config ={ method: 'GET', url:url, params: params ? params : {}, headers: headers ? headers : {} }; return request(config); }, post(url, data, headers){ const config ={ method: 'POST', url:url, data: data ? data : {}, headers: headers ? headers : {} }; return request(config); }, put(url, data, headers){ const config ={ method: 'PUT', url:url, data: data ? data : {}, headers: headers ? headers : {} }; return request(config); }, delete(url, data, headers){ const config ={ method: 'DELETE', url:url, data: data ? data : {}, headers: headers ? headers : {} }; return request(config); }, }; export default http;
(3)api.js 用来统一管理接口 url
import http from "./http"; const urls={ department:'/api/Department' }; export default { getDepartments(){ return http.get(urls.department); } }
(4)在组件中调用:
import api,然后在调用 api.getDepartments()
<template> <div> </div> </template> <script> import api from '../network/api'; export default { name: 'Attendance', data() { return { }; }, methods:{ }, mounted(){ api.getDepartments() .then(res=>{ if(res.status === 200){ if(res.data){ console.log(res.data); } } }) .catch(error=>{ console.log(error); }); } } </script> <style scoped> </style>
四、解决开发时跨域问题
1.跨域问题的产生:
前端与后端分开部署,IP或端口不同,那么,来自前端的 javascript 代码,访问后端的接口,将产生跨域问题。
跨域问题的本质是浏览器基于同源策略的一种安全限制。同源策略要求协议、域名、端口三者必须完全相同,否则浏览器将阻止跨域请求,以防止恶意网站窃取数据。
这种保护机制虽然增强了安全性,但也给不同站点之间的正常数据交互带来了阻碍,例如,分开部署的前后端之间的数据交互。
2.跨域问题的解决:
解决跨域问题的方法包括在服务端设置 CORS(跨资源共享)策略,允许特定或所有源进行请求,以及使用代理服务器等方式绕过同源策略的限制。
在开发环境中,Vue 采用后者(使用代理服务器)以避免跨域问题:在 Vue CLI 中配置 vue.config.js,设置 devServer.proxy,将指定的请求代理到目标服务器(即后端)。
修改 vue.config.js 文件,添加如下配置:
//... module.exports = defineConfig({ //... devServer: { port: 8080, proxy: { '/api': { target: 'http://localhost:8088', changeOrigin: true, pathRewrite: { '^/api': '/api' } } } } })
其中,devServer :即前端服务器;
port:指出前端服务器的哪个端口需要配置代理;
proxy :即代理;
'/api':指出哪类请求需要代理;
target:指出代理需要访问的目标,用于配置后端服务器地址;
pathRewrite:指出如何重写请求的路径(使用正则表达式进行匹配)。
3.请求路径的组装过程,示例如下:
(1)request.js 中的axios baseURL ('') + api.js 中的 url(/api/Department),生成:/api/Department,
此时,在客户端浏览器看来,发起了一个【http://{前端服务器IP}:8080/api/Department】请求;
(2)请求的目标端口是 8080,且路径“/api/Department”是以 “/api”开头,被 vue.config.js 中的代理 devServer. proxy.'/api' 捕获;
(3)根据 pathRewrite 配置,代理将请求路径 “/api/Department” 重写为 “/api/Department” 【示例中,将/api重写为/api,所以保持不变 】;
(4)代理将重写后的请求路径与 target 结合,生成最终的请求路径:“http://localhost:8088/api/Department”【注意,端口不同】;
(5)由代理访问地址:“http://localhost:8088/api/Department”,并拿到返回结果;
此时,完成了一次对【http://{后端服务器IP}:8088/api/Department】请求与返回;
(6)代理拿到后端返回结果并将其发回给浏览器【在客户端浏览器看来,收到了【http://{前端服务器IP}:8080/api/Department】请求的响应】。
之后浏览器将数据返回给 api.js 中对应的回调函数(then参数函数)。
完成一次跨域访问。
注意:由 request.js 中的 baseURL 和 api.js 中的 url 相组合而生成路径,它的开头部分须与 devServer.proxy 中配置的路径相同,否则无法匹配,而导致未能启用代理,将仍然报跨域错误。