当一个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的路由不支持这个,只能用户自己来处理了。
声明:本站所有文章和图片,如无特殊说明,均为原创发布。商业转载请联系作者获得授权,非商业转载请注明出处。