跨域简单请求变成非简单请求导致的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的路由不支持这个,只能用户自己来处理了。



 

修改时间 2018-05-16

真诚赞赏,手留余香
赞赏
随机推荐
macOS重装Adobe Photoshop CS6
Electron 简介
Node.js ORM 框架 Sequelize.js 教程
photoshop 数位板 两小时练习
Vue.js 如何添加全局函数或变量?
CentOS 如何防止 SSH 长时间不操作自动断开连接
git fetch与git pull的区别
Normalize.css 和 CSS Reset 的区别
详解移动端网页适配开发
如何解决mysql delete表数据后,表空间大小不变的问题