Vue中配置代理服务器解决跨域问题

首先复习一下同源策略和跨域请求

  • 同源策略规定发送网络请求必须有三个一致,协议名,主机名和端口号=>例如:http//:localhost:8081
  • 协议名为http,主机名为localhost,端口号为8081,那么你就只能通过ajax联系协议名为http,主机名为localhost,端口号为8081的服务器

解决跨域有以下几种方法:

  • 1.cors:这是真正意义上的解决跨域,它通过给服务器设置一些跨域响应头的方法来解决跨域,响应返回数据的同时也会返回这些特殊的响应头,但是真正开发当中很少使用,这会造成所有人都能获取到你的数据,这也是后端的事
  • 2.Jsonp:通过借助script标签里面的src属性来引入外部资源的时候不受同源策略限制的这样一个特点办到的,但是jsonp巧妙归巧妙,真正开发用得微乎其微,因为它是需要前端和后端一起努力才能做到的事,最致命的是它只能解决get请求的跨域问题
  • 3.代理服务器(开发中用的最多):代理服务器就相当于我们日常生活中的”房屋中介”,它最厉害的地方在于,它所处的位置跟我们是一样的(端口号始终与页面保持一致),这样我们就可以向代理服务器发送请求,而代理服务器进而想真正拥有数据的服务器发送请求,服务器向代理服务器返回数据,代理服务器再返回数据给页面,因为代理服务器和真正拥有数据的服务器均为服务器,而服务器与服务器之间传数据是不需要通过ajax的,就不存在跨域问题,也就是不受同源策略的影响了.
    image

开启代理服务器一般有两种方法:

  1. njinx[后端常用,这里不讲]
  2. Vue-cli[前端常用,重点讲解]

Vue-cli中代理服务器的使用方法:

Vue-cli官网

  • 找到:devServer.proxy,便是代理服务器
    image

配置代理方法一:

  • 在项目根目录中的 vue.config.js 文件当中填入以下代码(这里展示完整的代码):
    const { defineConfig } = require('@vue/cli-service')
    module.exports = defineConfig({
      transpileDependencies: true,
      lintOnSave:false , /*关闭语法检查*/

      // 配置代理方法一: 开启代理服务器(代码片段)-------------------
      devServer: {
        // 这里填的是远端服务器的url
        proxy: 'http://localhost:5000'
      }
      // ------------------------------------------
    })
  • 随后在App组件当中使用axios发送ajax请求即可
    <template>
        <div>
            <button @click="getStudents">点击获取学生信息</button>
        </div>
    </template>

    <script>
    //首先引入axios
        import axios from 'axios'

        export default {
            name:'App',
            methods: {
                getStudents(){
                    // 发送axios请求(切记这里填的是代理服务器的url)
                    axios.get('http://localhost:8081/students').then(
                        response => {
                            // 成功返回数据返回
                            console.log('数据请求成功',response.data)
                        },
                        error => {
                            // 失败返回错误信息
                            console.log('数据请求失败',error.message)
                        }
                    )
                }
            },

        }
    </script>

结果展示:

image

  • 失败的请求展示如下:
    image

注意点

  • 代理服务器并不是将所有收到的请求都会转发给服务器的,当你请求的资源,你本身就有,那么代理服务器就不会向服务器发送请求,如下:
  • 这里我本身就有 students文件,那么我再向代理服务器发送请求,代理服务器就不会像服务器发送请求,响应数据了,它会响应我自身有的数据
    image

结果展示:

image

由此可见,这种配置代理的方法(方法一)有以下优缺点

  1. 优点:配置简单,请求资源时直接发给前端(8080)即可。
  2. 缺点:不能配置多个代理,不能灵活的控制请求是否走代理。
  3. 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器 (优先匹配前端资源)

配置代理方法二:(重点是搞清楚请求前缀和请求url的改写)

  • 在项目根目录中的 vue.config.js 文件当中填入以下代码(这里展示完整的代码):
    const { defineConfig } = require('@vue/cli-service')
    module.exports = defineConfig({
      transpileDependencies: true,
      lintOnSave:false , /*关闭语法检查*/

      // 配置代里方法二(代码片段)-------------------
      devServer: {
        proxy: {
          // 请求前缀(超级重点),匹配所有以 '/student'开头的请求路径
          // 其实就是控制代理是否向远端服务器发送请求
          '/student': {
            // 代理目标的基础路径,即远端服务器的url
            target: 'http://localhost:5000',
            //[正则表达式](超级重点)改写向远端服务器发送的请求url,不改的话会404
            pathRewrite: {'^/student': ''},
            ws: true, //用于支持websocket
            changeOrigin: true //让代理服务器学会谎报来源的端口号
          },

          '/car': {
            // 代理目标的基础路径,即远端服务器的url
            target: 'http://localhost:5001',
            //[正则表达式]改写向远端服务器发送的请求url,不改的话会404
            pathRewrite: {'^/car': ''},
            ws: true, //用于支持websocket
            changeOrigin: true //让代理服务器学会谎报来源的端口号
          },
        }
      }
      // ----------------------------------------
    })
    /*
       changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
       changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
       changeOrigin默认值为true
    */
  • 随后在App组件当中使用axios发送ajax请求即可
    <template>
        <div>
            <button @click="getStudents">点击获取学生信息</button>
            <button @click="getCars">点击获取汽车信息</button>
        </div>
    </template>

    <script>
        // 首先引入axios
        import axios from 'axios'

        export default {
            name:'App',
            methods: {
                // 使用方法二配置代理就可以同时配置多个代理了!

                // 1.请求学生的信息
                getStudents(){
                    // 发送axios请求(切记这里填的是代理服务器的url)
                    // 配置方法二,需要在端口号后面配置请求前缀:student
                    axios.get('http://localhost:8081/student/students').then(
                        response => {
                            // 成功返回数据返回
                            console.log('数据请求成功',response.data)
                        },
                        error => {
                            // 失败返回错误信息
                            console.log('数据请求失败',error.message)
                        }
                    )
                },

                // 2.请求汽车的信息
                getCars(){
                    // 发送axios请求(切记这里填的是代理服务器的url)
                    // 配置方法二,需要在端口号后面配置请求前缀:car
                    axios.get('http://localhost:8081/car/cars').then(
                        response => {
                            // 成功返回数据返回
                            console.log('数据请求成功',response.data)
                        },
                        error => {
                            // 失败返回错误信息
                            console.log('数据请求失败',error.message)
                        }
                    )
                }
            },

        }
    </script>

结果展示:

image

由此可见配置方法二有以下优缺点:

  1. 优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
  2. 缺点:配置略微繁琐,请求资源时必须加前缀。