Vue.js

Vue.js axios请求跨域解决

2021-03-17  本文已影响0人  江河湖海琴瑟琵琶

开发环境

前端VUE运行在本地:http://localhost:8088
后端API运行地址为http://www.imagemix.com
现在要通过axios调用后端接口,域名不同,浏览器依据同源策略,出现跨域问题.

原理

当我们在代码中写的 (get,post)请求跨域时, 浏览器在发出真正的请求前, 会自动的向服务端发出一个OPTIONS预检请求, 然后浏览器通过分析服务端对OPTIONS请求的响应头,来判断服务端是否支持跨域.

完整步骤

  1. 浏览器发出OPTIONS请求

    跨域请求
  2. 服务端收到请求,并做出响应


    服务端返回的响应
  3. 浏览器分析服务端的响应信息,判断是否支持跨域.
    这次OPTIONS请求服务端返回信息中没有Access-Control-Allow-Origin字段,浏览器判定服务端不支持跨域, 于是后续请求不会执行

    浏览器检测结果

解决方法

如果服务端支持跨域, 那么服务端应该正确响应这个OPTIONS请求,只要在返回的消息头中加上对应字段就行了

#在项目的入口文件里
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '*';
        header('Access-Control-Allow-Origin:' . $origin);
        header('Access-Control-Allow-Credentials:true');
        header('Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS');
        header('Access-Control-Allow-Headers:Origin,Token, No-Cache, uniqid, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With');
        header('Access-Control-Expose-Headers:uniqid');
        if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
            exit();
        }

其他说明

  1. Access-Control-Allow-Origin: *表示允许哪个域名跨域访问

  2. Access-Control-Allow-Headers:允许浏览器跨域时携带的自定义头信息.
    vue需要携带token,uniqid字段发送请求到服务器,在预检请求中需要告诉浏览器支持的字段,否则前端会报错

  3. 前后分离,导致生成的验证码无法通过cookie验证, 于是我在返回验证码图片的同时返回了一个自定义header表示验证码的唯一ID uniqid = df2341f55fzz3vbd , vue中需要记录这个值, 提交表单时再传上来.
    需要加上header('Access-Control-Expose-Headers:uniqid');vue才能取出这个自定义uniqid

var uniqid = response.headers.uniqid

另外记录axios携带header的方式
get请求

axios
        .get(
          process.env.BASE_API+'/index.php/Home/Index/Code',
          {
            responseType: 'arraybuffer',
            headers:{
              uniqid:_that.formData.headers.uniqid
            }
          })
        .then(function(response){
          console.log(response)
          var contentType = response.headers['content-type']
          var uniqid = response.headers.uniqid
          sessionStorage.setItem('uniqid',uniqid)
          console.log(uniqid)
          var blob = new Blob([response.data],{type:contentType})
          _that.formData.verify =  URL.createObjectURL(blob)
        })
    },
上一篇下一篇

猜你喜欢

热点阅读