您的位置:首页 > 前端开发 > 技术笔记

跨域请求时出现options请求的原因和解决

2018-02-01 14:05:34

原因

具体术语我就不说了,记不住,只说原理。
在跨域时,请求分为两种:

1、简单请求,只包括get、post和head
2、复杂请求,就包括剩余的那些请求方式了

它们的区别就是,如果发送请求时设置了头信息,就变成了复杂请求,如下

axios({
    method:'get',
    headers:{
        Accept:'application/json',
        Authorization:adasdfadfasdfsewe
    },
    params:{}
})

以上就是复杂请求,复杂请求,在请求的时候,浏览器会先发送了一个options请求,此请求貌似只传了url地址,也没传过去任何参数和你定义的头信息。如果服务器能返回设了头信息的那些字段,就说明服务器是允许的,然后才会发送你指定的方式的请求。

注意,假如服务器对请求做了令牌验证,而令牌正好是在头信息内设置的,那么,此options请求是没有携带令牌滴,那么此请求就通不过服务器的验证。就会返回令牌错误提示。

解决

在服务器端检测接收到的请求是否是options请求,是,则主动给客户端返回一个204状态码,空数据,浏览器接收到这个内容,就知道了服务器允许你进行下一步访问,浏览器会自动发送真正的get或post这类请求了,服务端设置如:nodejs下express设置如下

/*允许跨域 */
router.use(function(req, res, next) {
    //console.log(req);
    console.log(req.method);
    res.header("Access-Control-Allow-Origin", "*");
    res.header('Access-Control-Allow-Methods', 'OPTIONS,GET,POST,PUT,DELETE');
    res.header("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,Authorization");
    res.header("cache-control", "no-cache");
    res.header("content-type", "application/json; charset=utf-8");
    res.header("ETag", '');
    //header头信息设置结束后,结束程序往下执行,返回
    if(req.method.toLocaleLowerCase() === 'options'){
        res.status(204);
        return res.json({});   //直接返回空数据,结束此次请求
    }else{
        next();
    }
});


more 最近