axios基本使用及跨域问题详解

前端请求自然也发展迅速,从原生的XHR到jquery ajax,再到现在的axios和fetch。axios( http://www.axios-js.com/zh-cn/ )是Vue推荐的http库,这个还是要了解一点的。

安装

$ npm install axios

基本使用的例子

1、在main.js中(肯定得创一个Vue脚手架的工程)import

import axios from 'axios'

2、使用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 http

3、封装完怎么用?
同样,把封装好的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等攻击。所谓同源是指 协议+域名+端口 三者相同,即便两个不同的域名指向同一个地址,也非同源。


image.png

2、什么是跨域?
当一个请求url的 协议、域名、端口 三者之间任意一个 与当前页面url不同 即为跨域

比如我现在有一个自己写的接口

http://localhost/allPHPcode/starbuckBackend/menu.php

它返回menu的json数据


image.png

现在向它发起请求

//自己写的一个接口,不允许跨域
      this.$axios({
        url:`localhost/allPHPcode/starbuckBackend/menu.php`
      }).then((res) => {
        console.log(res);
      }).catch((error) => {
        console.log(error);
      })

报错


image.png

端口号不同,存在跨域
3、解决办法一——允许跨域
查看请求自己写的menu接口时的网络面板


image.png

查看请求天气接口时的网络面板
image.png

对比就可以发现,如果要允许跨域,在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后再次请求


image.png

4、解决办法二——代理
通过中间件来解决跨域问题,浏览器有跨域限制,但是服务器没有跨域限制,所以中间件其实就是服务器(服务器对数据进行了转发而已)


image.png

首先在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                //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
      }
    }
  }
})

再次发起请求,问题解决

image.png

关于pathRewrite可以看这两篇文章
[1]:https://juejin.cn/post/7041441723238580238
[2]:https://www.cnblogs.com/hanguidong/p/9460495.html

以上例子的源码:https://github.com/AnnGreen1/axios-demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容