使用vue脚手架解决ajax跨域请求

发送ajax请求的4种方式

  • xhr方法: new XMLHttpRequest() (最原始写法) xhr.open() xhr.send()
  • jQuery方法: $get $post
  • axios :(Promise风格)
  • fetch:(Promise风格),fetch的兼容性较差
    jQuery和axios 是对 xhr方法的封装,而fetch方法和xhr方法是平级的,都在window对象身上。

在Vue中推荐使用axios发送请求。

使用axios发送ajax请求

  • 安装 :npm i axios
  • 引入:import axios from 'axios'
  • 发送axios请求
      axios.get('http://localhost:5000/students').then(
        response => {
          console.log("响应体内容", response.data)
        },
        error => {
          console.log("请求失败", error.message)
        }
      )

跨域问题

跨域的理解

同源请求是指协议名、主机名、端口号三者一样
跨域请求就是是指协议名、主机名、端口号三者有任何一个不一样都是跨域请求。
而且跨域请求是请求发出去了,服务器接收并返回了结果,只是浏览器没有接收响应结果。
在这里插入图片描述

跨域的报错

在这里插入图片描述

跨域的解决

jsonp 和 CORS

我们js的跨域解决有两种办法:jsonp 和 CORS

jsonp 和 CORS的缺点
  • jsonp 靠 <script>来实现跨域请求
    前端需要定义函数,而且后端需要调用该函数
    jsonp只能解决GET请求跨域,所以jsonp请求很少用

  • CORS通过设置响应头来实现跨域请求,由后端人员添加响应头
    浏览器一看到后端携带的响应头就不拦截数据了,就可以实现跨域请求。
    造成的问题是任何人都可以向该后端要数据,是不安全的

配置代理服务器(——正向代理)

配置代理服务器原理

原理:
设置一个代理服务器,它的协议名、主机名、端口号和前端的一模一样,这样前端访问该代理服务器就没有跨域问题了。
当该代理服务器收到前端的请求,再向其他服务器发送该请求,获取数据,之后将数据返回给前端。
(服务器之间不是通过ajax请求发送信息自然也没有跨域这个问题了)
在这里插入图片描述

配置代理服务器方法

有两种方法:

  • nginx: 使用nginx创建一个代理服务器 (服务器作为中间层,我们自己进行配置解决跨域问题)
  • node:使用node创建一个代理服务器 (服务器作为中间层,我们自己进行配置解决跨域问题)
  • vuecli (vue脚手架)

这里使用vuecli 配置代理服务器

方法一
  • vue.config.js:用来设置脚手架的全局配置。
    配置代理服务器需要对vue.config.js做如下配置:
module.exports = {
  devServer: {
    // 这里配置的是向哪台服务器发送请求
    // (代理服务器的地址不用管他会自动配置)
    proxy: '协议名://主机名:端口号'
  }
}
  • 使用代理服务器
    当前前端浏览器的地址是:http://localhost:8080
    需要向后端:http://localhost:5000/students 请求数据,出现跨域问题。
    使用代理服务器解决跨域:

vue.config.js配置:

module.exports = {
  devServer: {
    // 这里配置的是向哪台服务器发送请求
    // (代理服务器的地址不用管他会自动配置)
    proxy: 'http://localhost:5000'
  }
}

请求发送:

      axios.get('http://localhost:8080/students').then(
        response => {
          console.log("响应体内容", response.data)
        },
        error => {
          console.log("请求失败", error.message)
        }

需要注意的一个问题:服务器的具体请求路径 /students 不能直接在vue.config.js中直接写,还是写在ajax请求地址后面,此时ajax请求地址需要换成http://localhost:8080(当请求地址的协议域名端口号和程序运行的协议域名端口号一样时请求的时候可以省略协议域名端口号,即此时http://localhost:8080也可以省略不写)。

  • 问题:
    (1) 当请求的资源代理服务器本身就有就不会转发请求,public文件夹中的东西就是代理服务器的资源。
    如果请求名称和public文件夹中资源的名称同名就会返回public中的资源,但是我们如果希望该请求走代理这种方法就不合适了
    (2) 只能配置一个请求代理服务器,即只能向一个服务器转发请求
方法二

vue.config.js的第二种配置方式:
eg:
vue.config.js配置

devServer: {
    proxy: {
      '/api': {// '/api'请求前缀,表示只要请求前缀是/api就走代理
        target: '<http://localhost:5000>',
        // 将以api开头的请求,将开头的/api去掉,否则目标服务器会找不到路径的
        pathRewrite: { '^/api': '' },
        ws: true,//用于支持webscoket

        //用与向目标服务器说明自己是哪台服务器(即配置请求头host)
        // 如果为false则自己是哪台服务器就说是哪台(host为8080)
        // 如果为true,则目标服务器是哪台就说自己是哪台服务器(host为5000)
        changeOrigin:true
      },
      // 可以设置多台服务器
      '/demo': {
        target: '<http://localhost:5001>',
        pathRewrite: { '^/demo': '' },
        ws: true,
        changeOrigin:true
      }
    }
  }

请求发送:

      axios.get('http://localhost:8080/api/students').then(
        response => {
          console.log("响应体内容", response.data)
        },
        error => {
          console.log("请求失败", error.message)
        }
  • 优点:可以配置堕胎服务器,可以控制请求是否走代理。

案例:github用户搜索案例

实现效果:
在这里插入图片描述
代码获取:
https://github.com/wangliyang-max/qiandaun/tree/master/VUE/vue_test/20_src_github%E6%90%9C%E7%B4%A2%E6%A1%88%E4%BE%8B

发送ajax请求的库vue-resource

vue-resource是vue的插件库,是对xhr的封装。

  • 安装 :npm i vue-resource
  • 引入:因为是vue的一个插件库,在main.js中进行引入
    import vueResource from 'vue-resource'
    并且需要使用vue.app()进行配置:
    Vue.use(vueResource)
  • 是应该插件之后每个vm、vc身上都多出来一个$http对象属性。
  • 使用:和axios的用法一摸一样,只需要将axios发送的请求的axios换成this.$http
    eg:
    get请求:
this.$http.get(`https://api.github.com/search/users?q=${this.keyword}`)
                .then(response => {
                    // console.log("请求成功了", response.data.items)
                    this.$bus.$emit("getUsers", { isLoading: false, errMsg: '', users: response.data.items })
                    },
                    error => {
                        // console.log("请求失败了", error.message)
                        this.$bus.$emit("getUsers", { isLoading: false, errMsg: error.message, users:[]})

                    }
                )

最常用的发送ajax请求的方法还是axios

Logo

前往低代码交流专区

更多推荐