我正在使用流行的FOSRestBundle在Symfony中开发RESTful API。 API已经完成,但它仍然不支持跨域调用。
我已经尝试添加NelmioCorsBundle,但我没能让它正常工作。我已经开始测试不同的东西,比如添加
headers('Access-Control-Allow-Origin', '*');
手动作为app_dev.php中的第一行代码。我知道它可能不是添加它的最佳位置,但我只是想知道它是否真的在做任何事情。
现在有了一个有趣的部分:
当我只发送GET请求时,会添加标头。当我发送成功的 POST请求时,标题也会被添加,我得到一个我的AJAX调用可以读取的响应。但是,当API突然抛出异常时,响应中没有添加CORS头,因此我的浏览器拒绝加载响应。我不知道这是否是正常行为,但由于我的API几乎所有内容都抛出异常(缺少参数或参数格式错误,......)这使得我的API在使用AJAX调用时无用?
我已经设置了一个合适的监听器来提供这些标题:
namespace MyComp\MyBundle\Listeners;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
class CorsListener
{
public function onKernelResponse(FilterResponseEvent $event)
{
$responseHeaders = $event->getResponse()->headers;
$responseHeaders->set('Access-Control-Allow-Headers', 'origin, content-type, accept');
$responseHeaders->set('Access-Control-Allow-Origin', '*');
$responseHeaders->set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, PATCH, OPTIONS');
}
}
并将其注册在我的 services.yml 文件中:
MyCompMyBundle.cors.listener:
class: MyComp\MyBundle\Listeners\CorsListener
tags:
- { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
添加
时die("---");
在CorsListener中,当我尝试发出请求时,它正确地输出了这个字符串。如果API抛出异常并不重要,所以我确定每个请求都会调用此代码块。
例如:
API._post("access-tokens", undefined, {"email": "xxx@hotmail.com", "password": "xxx"}, function(e) { console.log(e) })
哪个电话:
_post: function(endpoint, id, dataObject, completionHandler) {
var url = this._baseUrl + endpoint;
url = typeof id !== "undefined" ? url + "/" + id : url;
$.ajax({
url: url,
type: 'POST',
// this._encodeData converts the data object to a x-www-form-encoded string
data: this._encodeData(dataObject),
crossDomain: true,
success: function(data) {
completionHandler({"success": data});
},
error: function(e) {
completionHandler({"error": e});
}
});
}
返回带有以下标题的响应:
Access-Control-Allow-Headers:origin, content-type, accept
Access-Control-Allow-Methods:POST, GET, PUT, DELETE, PATCH, OPTIONS
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Connection:close
Content-Type:application/json
Host:127.0.0.1:8000
(left out some unimportant bits like date and php version)
如果我提供了正确的电子邮件/密码组合。如果我输入垃圾或遗漏登录参数,API应抛出并返回此错误:
{
"code": 500,
"message": "Log in using either fb-id/access-token or email/password!"
}
然而,当API确实抛出此错误时,即使仍在调用CorsListener中的代码,我得到的唯一响应头是:
Connection → close
Content-type → text/html; charset=UTF-8
Host → 127.0.0.1:8000
再次阻止了AJAX调用。
当我在Postman中发送带有垃圾或遗忘参数的相同请求时,它会返回a
500 Internal Server Error
使用正确的标题
Access-Control-Allow-Headers → origin, content-type, accept
Access-Control-Allow-Methods → POST, GET, PUT, DELETE, PATCH, OPTIONS
Access-Control-Allow-Origin → *
Cache-Control → no-cache
Etc...
和内容
{
"code": 500,
"message": "Log in using either fb-id/access-token or email/password!"
}
为什么我的服务器没有像处理Postman一样处理AJAX调用?我已经读到Postman没有发送一个Origin标题,但是我认为这不会产生如此大的差异?
我做错了吗?或者我只是想做一些不可能的事情?如果是这样,处理我的方案的正确方法是什么?我不仅试图解决我的问题,我还试图理解根是什么,所以我可以从中学习。
答案 0 :(得分:0)
我清除了Symfony缓存文件夹后,这些问题自行解决了。