用于放置/删除的CORS Cakephp 3.0预检失败

时间:2015-05-26 15:34:06

标签: angularjs cors cakephp-3.0

我正在努力让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, POST, PUT, DELETE, OPTIONS");
}

CakePHP routes.php

$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, POST, PUT, DELETE, 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';

CAKEPHP webroot / index.php

// 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, POST, OPTIONS, PUT, DELETE");

    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

    exit(0);
}

1 个答案:

答案 0 :(得分: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();

如果您需要文档中的更多信息,请参见corscommon mistake
希望对您有所帮助。