前端如何配合服务端进行 CORS 跨域

最近正在用 vue.js + vuex + axios 开发一个后台管理的项目。由于服务端的接口地址与 web 的访问不在同一个域里面,所以必须要处理跨域的问题,通过调研跨域的方法,最终决定使用目前比较流行的 CORS 来处理跨域 ,以下介绍在使用 cors 的时候遇到的那些坑,以及处理方法。

 

现在所有的浏览器基本上都支持 CORS(IE需要10以上),所以只需要服务器实现 CORS 的接口,就可以跨域通讯了。服务端基本的配置如下:

"Access-Control-Allow-Origin" => $host_name,
"Access-Control-Allow-Headers" => "x-token,x-uid,x-token-check,x-requested-with,content-type,Host,auth-token,Authorization",

服务端配置完以后,前端在发起请求,就会变成两个。首先会向服务器发一个预检请求。

从图中可以看到请求的方法是:OTPTION。这个请求只要是用于检查

Access-Control-Allow-Origin

Access-Control-Request-Headers 这两个字段,确认允许跨域请求以后,才正式发出我们想要的请求

完成这一步,CORS 请求基本上就成功了。

但是请别高兴的太早,CORS 请求默认是不发送 Cookies 和 HTTP 认证信息的。而服务端需要

”Access-Control-Expose-Headers” => ‘auth-token’

通过 Cookies 里面的信息来判断的依据,所以这时候,我们就要这是 withCredentials 属性。

一方面需要服务端同意发送 Cookies,指向 Access-Control-Allow-Credentials 字段。

”Access-Control-Expose-Headers” => ‘auth-token’

另一方面,前端也必须在 ajax 请求的设置 withCredentials 属性。(这里是用的是 Axios 的配置)

const axiosInstance = axios.create({ withCredentials: true })

服务端和前端同时设置完 withCredentials 属性之后,就可以自动发送 Cookies 。

需要注意的是,在 Header 里面有些自定的字段,前端没有办法获取到。例如用于自定义存放 token 的字段,我们采用了 auth-token ,默认情况下是不允许获取的。这时候服务端需要设置 Access-Control-Expose-Headers 字段,允许请求中携带 auth-token。

"Access-Control-Expose-Headers" => 'auth-token'

完成以上步骤,就大功告成了,以下贴出服务端与前端设置,以供参考:

PHP 设置 CORS 头部

function get_cross_headers(){
    $host_name = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : "*";
    $headers = [
        "Access-Control-Allow-Origin" => $host_name,
        "Access-Control-Allow-Credentials" => 'true',
        "Access-Control-Allow-Headers" => "x-token,x-uid,x-token-check,x-requested-with,content-type,Host,auth-token,Authorization",
        "Access-Control-Expose-Headers" => 'auth-token'
    ];
    return $headers;
}

Axios 配置

const axiosInstance = axios.create({
  withCredentials: true
})
axiosInstance.interceptors.request.use(config => {
  const token = ls.get('token') //从 localstorage 中获取token
  if (token) {
    config.headers['auth-token'] = token
  }
  return config
}, function (error) {
  return Promise.reject(error)
})
axiosInstance.interceptors.response.use(response => {
  const token = response.headers['auth-token']
  token && ls.set('token', token) //将 token 存入 localstorage
  return response.data
}, function (error) {
  return Promise.reject(error)
})

 

 

原文:http://lilin.me/2017/05/02/ajax-with-cors/

 

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值