我正在尝试让CORS在我的应用程序中运行.但预检OPTIONS调用PUT和DELETE总是失败.例如PUT请求:
OPTIONS /api/events/5b165c71-0676-4d67-aceb-5546aff8ea03 HTTP/1.1 Host: rest.app Connection: keep-alive Access-Control-Request-Method: PUT Access-Control-Request-Headers: accept,content-type Origin: http://frontend.app User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/43.0.2357.81 Safari/537.36 Accept: */* Referer: http://frontend.app/events/5b165c71-0676-4d67-aceb-5546aff8ea03/edit Accept-Encoding: gzip,deflate,sdch Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,fr;q=0.2,it;q=0.2
和我服务器的响应(CakePHP 3.0)
Access-Control-Allow-Credentials:true Access-Control-Allow-Headers:accept,content-type Access-Control-Allow-Methods:GET,POST,PUT,DELETE,OPTIONS Access-Control-Allow-Origin:http://frontend.app Access-Control-Max-Age:86400 Connection:Keep-Alive Content-Type:text/html; charset=UTF-8 Date:Tue,26 May 2015 15:21:24 GMT Keep-Alive:timeout=5,max=100 Server:Apache transfer-encoding:chunked X-DEBUGKIT-ID:75441af3-02b0-4945-a82c-5607287d4994 X-Powered-By:PHP/5.6.7
错误消息是:
OPTIONS http://rest.app/api/events/5b165c71-0676-4d67-aceb-5546aff8ea03 XMLHttpRequest cannot load http://rest.app/api/events/5b165c71-0676-4d67-aceb-5546aff8ea03. Invalid HTTP status code 404
所以不允许实际的请求.
我在Angular中将withCredentials标志设置为true.
我还在尝试修复CORS问题或者是cakePHP的错误吗?我试图用PHP和htaccess设置标题.除了GET和POST之外什么都没有用.
编辑:
头
if (isset($_SERVER['HTTP_ORIGIN'])) { header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}"); header('Access-Control-Allow-Credentials: true'); header('Access-Control-Max-Age: 86400'); // cache for 1 day } if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) { header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); } if($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { header("Access-Control-Allow-Methods: GET,OPTIONS"); }
$routes->resources('Chapters');
EventController
public function edit($id = null) { // $this->autoRender = false; $event = $this->Events->get($id,[ 'contain' => [] ]); if ($this->request->is(['patch','post','put'])) { $event = $this->Events->patchEntity($event,$this->request->data); if ($this->Events->save($event)) { $message = 'The event has been saved.'; } else { $message = 'The event Could not be saved. Please,try again.'; } } $this->set(array( 'event' => $event,'_serialize' => array('message') )); }
使用Restangular进行调用的客户端.
Restangular.one('events',event.id).put();
$http与普通请求不同
xhr请求.
var xmlhttp = new XMLHttpRequest(); xmlhttp.open('PUT','http://rest.app/api/events/'+event.id,true); xmlhttp.send();
$HTTP
return $http({ url: 'http://rest.app/api/events/'+event.id,method: "PUT",data: event,dataType: 'json',withCredentials: true,headers: { 'Content-Type': 'application/json; charset=utf-8' } });
编辑2:
我刚刚发现,如果我这样做,即使我仍然收到错误,它仍然有效:
header("Access-Control-Allow-Methods: GET,OPTIONS"); if($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { die; }
这会让我更进一步吗?我知道那不是解决方案.
编辑3:
我刚刚使用这些更改.我不确定我是黑客还是我解决了CORS吧?!
AngularJS:
$httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers.common['X-Requested-With']; $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
// Allow from any origin if (isset($_SERVER['HTTP_ORIGIN'])) { header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}"); header('Access-Control-Allow-Credentials: true'); header('Access-Control-Max-Age: 86400'); // cache for 1 day } // Access-Control headers are received during OPTIONS requests if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) header("Access-Control-Allow-Methods: GET,OPTIONS,DELETE"); if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); exit(0); }
解决方法
如果CakePHP版本是> = 3.2
以下代码块可能会引导您进行操作.
以下代码块可能会引导您进行操作.
$this->response = $this->response->cors($this->request) ->allowOrigin(['*']) ->allowMethods(['GET']) // edit this with more method ->allowHeaders(['X-CSRF-Token']) //csrf protection for cors ->allowCredentials() ->exposeHeaders(['Link']) ->maxAge(60) ->build();
如果您需要有关文档的更多信息,请参阅cors和common mistake.
希望能帮助到你.