axios解决跨域原理(axios基本使用及跨域问题详解)
前端请求自然也发展迅速 ,从原生的XHR到jquery ajax ,再到现在的axios和fetch 。axios( https://axios-http.com/zh/ )是Vue推荐的http库 ,这个还是要了解一点的 。
安装 $ npm install axios基本使用的例子
1 、在main.js中(肯定得创一个Vue脚手架的工程)import
import axios from axios2 、使用axios
❌错误示范 import axios from axios const app = createApp(App) app.use(axios).mount(#app)这种写法不支持, 因为 axios 是第三方库, 不是vue的插件
✅正确示范!!!
在原型上进行绑定, 直接写原型链 import { createApp } from vue import App from ./App.vue import router from ./router import axios from axios const app = createApp(App) app.config.globalProperties.$axios = axios app.use(router).mount(#app)3 、简单发起一个请求
注意:这是高德地图提供的一个天气接口 ,高德接口已经把跨域的问题解决好了 ,允许跨域 //高德接口已经把跨域的问题解决好了 ,允许跨域 this.$axios({ url:`https://restapi.amap.com/v3/weather/weatherInfo?key=5737f6640c7a33f8fb22a952b298946b&city=340104`, }).then((res) => { console.log(res) }).catch((error)=>{ console.log(error); });封装axios
1 、直接用axios不好吗?为什么要封装?
说直白一点 ,就是接口不同时改个域名就行了 、可以统一管理请求 、条例清晰 、好维护
2 、怎么封装
要注意res是浏览器对请求响应的处理结果 ,res.status是http状态码 ,这是超文本传输协议响应状态的3位数字代码 ,在RFC 2616中规定好了 ,只有在data里面的status才能自己规定判断 import axios from "axios" //创建一个axios对象 const http = axios.create({ timeout: 5000 }) //设置请求的拦截器 http.interceptors.request.use(config => { // 在这里 ,可以配置请求头 、token等信息 return config }, error => { console.log(error); return Promise.reject(error) }) //设置响应的拦截器 http.interceptors.response.use(res => { //返回的响应数据 /** * res是浏览器对请求响应的处理结果,res.status是http状态码 , * 这是超文本传输协议响应状态的3位数字代码 ,在RFC 2616中规定好了 * 只有在data里面的status才能自己规定判断 */ console.log(res) console.log(res.data) const data = res.data if (res.status == 200) { if (data.status == 1 || data.status == 1000) { return Promise.resolve(data) } else { console.log(data) return Promise.reject(data) } } }, error => { if (error.response.status) { switch (error.response.status) { case 404: alert("请求路径找不到!") break; case 500: alert("服务器内部错误!") break; default: break; } } return Promise.reject(error) }) export default http3 、封装完怎么用?
同样,把封装好的axios实例加到原型上 import request from @/utils/request const app = createApp(App) app.config.globalProperties.$request = request app.mount(#app)之后请求
//自己封装的axios ,这个接口同样直接允许跨域 this.$request({ url:`http://wthrcdn.etouch.cn/weather_mini?city=%E5%BC%8B%E6%B1%9F`, }).then((res) => { console.log(res); }).catch((error)=>{ console.log(error); })有关跨域的问题
1 、什么是同源策略?
同源策略/SOP(Same origin policy)是一种约定 ,由Netscape公司1995年引入浏览器 ,它是浏览器最核心也最基本的安全功能 ,如果缺少了同源策略 ,浏览器很容易受到XSS 、CSFR等攻击 。所谓同源是指 协议+域名+端口 三者相同 ,即便两个不同的域名指向同一个地址 ,也非同源 。
2、什么是跨域?
当一个请求url的 协议 、域名 、端口 三者之间任意一个 与当前页面url不同 即为跨域比如我现在有一个自己写的接口
http://localhost/allPHPcode/starbuckBackend/menu.php它返回menu的json数据
现在向它发起请求 //自己写的一个接口 ,不允许跨域 this.$axios({ url:`localhost/allPHPcode/starbuckBackend/menu.php` }).then((res) => { console.log(res); }).catch((error) => { console.log(error); })报错
端口号不同 ,存在跨域
3、解决办法一——允许跨域
查看请求自己写的menu接口时的网络面板
查看请求天气接口时的网络面板
对比就可以发现 ,如果要允许跨域 ,在php顶部加上以下header即可 // 跨域问题处理 header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE"); header(Access-Control-Allow-Headers:x-requested-with,content-type);添加header后再次请求
4 、解决办法二——代理
通过中间件来解决跨域问题 ,浏览器有跨域限制,但是服务器没有跨域限制 ,所以中间件其实就是服务器(服务器对数据进行了转发而已)
首先在vue.config.js文件里配置一下
const { defineConfig } = require(@vue/cli-service) module.exports = defineConfig({ transpileDependencies: true, devServer:{ proxy:{ /localhost:{ //这个就是的标识 ,当接口用 localhost 开头才用代理 target:http://localhost, //这是代理到哪里 pathRewrite:{ ^/localhost:}, //这个是路径重写,比如代理的标识是 localhost ,但是要请求的路径里没有 localhost 这个字符串 ,所以用pathRwrite把 localhost 换成空字符串 ,也就是删掉 ,之后再拼到target上就合适了 changeOrigin:true //开启代理:在本地会创建一个虚拟服务端 ,然后发送请求的数据 ,并同时接收请求的数据 ,这样服务端和服务端进行数据的交互就不会有跨域问题 } } } })再次发起请求 ,问题解决
关于pathRewrite可以看这两篇文章
[1]:https://juejin.cn/post/7041441723238580238
[2]:https://www.cnblogs.com/hanguidong/p/9460495.html以上例子的源码:https://github.com/AnnGreen1/axios-demo
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!