Запрос предварительной проверки CORS, возвращающий HTTP 405

Я пытаюсь создать веб-службу RESTful и застрял в реализации запросов PUT. Я пробовал и не смог выполнить другие ответы на этом сайте и различные статьи из Mozilla.

Запрос создается из домена wwwtest.dev-box и он отправляется в test.dev-box (в основном, test.dev-box приложение, вызывающее test.dev-box приложение). Вот заголовки, которые я захватил из заголовков Live HTTP:

 http://test.dev-box/resource/v1/data/user/1 OPTIONS /resource/v1/data/user/1 HTTP/1.1 Host: test.dev-box User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Origin: http://wwwtest.dev-box Access-Control-Request-Method: PUT Connection: keep-alive HTTP/1.1 405 Method Not Allowed Date: Wed, 16 Oct 2013 16:15:58 GMT Server: Apache/2.2.15 (Red Hat) x-powered-by: PHP/5.3.27 Access-Control-Allow-Origin: http://wwwtest.dev-box Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS Access-Control-Max-Age: 1728000 Content-Length: 0 Allow: PUT Cache-Control: no-cache Connection: close Content-Type: text/html; charset=UTF-8 

Я использую фреймворк, поэтому все перенаправляется на web.php, который содержит следующий код в верхней части страницы (взятый из этой статьи MDN ):

 if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { header('Access-Control-Allow-Origin: http://wwwtest.dev-box'); header('Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS'); header('Access-Control-Max-Age: 1728000'); header("Content-Length: 0"); header("Content-Type: text/plain"); } else { header("HTTP/1.1 403 Access Forbidden"); header("Content-Type: text/plain"); } 

Перед тем, как мой код выполнит запрос PUT, он сначала отправит запрос OPTIONS перед запросом CORS (как вы можете видеть из вышеприведенного снимка). Необходимые заголовки должны быть прикреплены к ответу и сообщать запрашивающему, что PUT разрешен. К сожалению, как вы можете видеть из заголовков ответов выше, он все еще возвращает 405 Method Not Allowed, хотя PUT находится в методах контроля доступа-разрешения.

Это файл .htaccess для используемой среды (Silex):

 <IfModule mod_rewrite.c> Options -MultiViews RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ web.php [QSA,L] </IfModule> 

Я нашел ответ как нечто среднее между конфигурацией Apache и каркасом.

  1. Для конфигурации Apache вы можете либо поместить следующее в свою директиву VirtualHost, либо в файл .htaccess запрашиваемого домена (если он находится в .htaccess, запомните инкапсуляцию с тегами ifModule mod_headers.c). Настройка заголовков на странице, на которую перенаправляется mod_rewrite, не работает:

    Набор заголовков Access-Control-Allow-Origin " http: //wwwtest.dev-box "

    Набор заголовков Access-Control-Allow-Methods «GET, POST, HEAD, DELETE, PUT, OPTIONS»

  2. Для конфигурации Silex поместите следующее в свои маршруты приложений. Он в основном отправляет HTTP 200 OK для любого запроса OPTIONS, который он получает. Код, найденный в группе Silex Google :

    $ app-> match ("{url}", function ($ url) use ($ app) {return "OK";}) -> assert ('url', '. *') -> method ("OPTIONS" );

Оба этапа должны быть завершены, чтобы приложение RESTful функционировало должным образом.

405 относится к фактическому запросу предполетного / ОПЦИИ. Ваш сервер отклоняет предполетный пост, так как запросы OPTIONS в целом не принимаются вашим сервером. Вам нужно будет изменить конфигурацию своего сервера, чтобы принимать запросы OPTIONS. Простое включение кода в файл PHP может быть недостаточно. Скорее всего, ваш веб-сервер / сервер приложений не знает этого глагола и отклоняет запрос до того, как он ударит ваш PHP-код.