跨域简单请求变成非简单请求导致的Bug

当一个api是GET请求, 地址是http://javascript.net.cn/user/comments 
正常的GET请求是没有问题的,但是有时候该GET请求会变成非简单请求。比如:

this.$http({
    method: 'GET',
    url: '/user/comments',
    params: {page:1, object_id:that.article.id, table_name:"portal_post"},
    headers: {
    'XX-Token':  tools.getCookie('token'),
    'XX-Device-Type': tools.getCookie('devices_type'),
    }
})
.then(function(response) {
    do something...
})
.catch(function(err){
    do something...
});

原因是HTTP的头信息超出以下几种字段时,就会变成非简单请求的跨域请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

Accept,
Accept-Language,
Content-Language,
Last-Event-ID,
Content-Type

如果程序中没有定义该api的option就会出现一些不可预知的错误。

我的解决方法,是在构造函数中,处理所有options请求:

if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With, XX-Token, XX-Device-Type');
    header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
    header('Access-Control-Max-Age: 1728000');
    exit;
}

因为header中有自定义字段(XX-Token),这样在浏览器中还可能存在另一种错误:

Request header field XX-Token is not allowed by Access-Control-Allow-Headers in preflight response.

解决方法,在 Access-Control-Allow-Headers 中,添加自定义字段 XX-Token。

header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With, XX-Token, XX-Device-Type');

 

在ThinkPHP5.1中,如果某个路由或者分组需要支持跨域请求,可以使用 Route::allowCrossDomain() 避免这个问题,
 

Route::get('new/:id', 'News/read')
    ->ext('html')
    ->allowCrossDomain(); 

但是很遗憾,ThinkPHP5.0的路由不支持这个,只能用户自己来处理了。



 

声明:本站所有文章和图片,如无特殊说明,均为原创发布。商业转载请联系作者获得授权,非商业转载请注明出处。
随机推荐
MySQL DATETIME 时间查询和转换
JavaScript 中 0.1 加 0.2 不等于 0.3 的原因和解决方法
Node.js readline 模块
WordPress 用户元信息 get_user_meta() 和 update_user_meta()
Express 使用 cookie-parser 处理 cookies
ReferenceError: __dirname is not defined in ES module scope
JavaScript screen对象
Notifications API