Eu criei um serviço RESTful básico com a estrutura SLIM PHP e agora estou tentando conectá-lo para que eu possa acessar o serviço de um projeto Angular.js. Eu li que Angular suporta CORS fora da caixa e tudo que eu precisava fazer era adicionar esta linha: Header set Access-Control-Allow-Origin "*"
ao meu arquivo .htaccess.
Eu fiz isso e meu REST aplicativo ainda está funcionando (não 500 erro interno do servidor de um mau. Htaccess), mas quando eu tento testá-lo de test-cors.org está jogando um erro.
Fired XHR event: loadstart
Fired XHR event: readystatechange
Fired XHR event: error
XHR status: 0
XHR status text:
Fired XHR event: loadend
Meu arquivo .htaccess se parece com isso
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /index.php [QSA,L]
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
Há algo mais que eu preciso adicionar ao meu .htaccess para fazer isso funcionar corretamente ou há outra maneira de ativar o CORS no meu servidor?
Desde que eu tinha tudo sendo encaminhado para index.php de qualquer maneira eu pensei que iria tentar definir os cabeçalhos em PHP em vez do arquivo .htaccess e funcionou! YAY! Aqui está o que eu adicionei ao index.php para qualquer outra pessoa com esse problema.
// Allow from any Origin
if (isset($_SERVER['HTTP_Origin'])) {
// should do a check here to match $_SERVER['HTTP_Origin'] to a
// whitelist of safe domains
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, PUT, DELETE, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
crédito vai para slashingweapon por sua resposta em esta questão
Como estou usando o Slim, adicionei essa rota para que as solicitações OPTIONS recebam uma resposta HTTP 200
// return HTTP 200 for HTTP OPTIONS requests
$app->map('/:x+', function($x) {
http_response_code(200);
})->via('OPTIONS');
O .htaccess
não deve usar add
em vez de set
?
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
Isto é o que funcionou para mim:
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "Origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
Como nesta resposta Custom HTTP Header para um arquivo específico você pode usar <File>
para habilitar o CORS para um único arquivo com este código:
<Files "index.php">
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
</Files>
Parece que você está usando uma versão antiga do slim (2.x). Você pode simplesmente adicionar as seguintes linhas ao .htaccess e não precisa fazer nada nos scripts PHP.
# Enable cross domain access control
SetEnvIf Origin "^http(s)?://(.+\.)?(domain_one\.com|domain_two\.net)$" REQUEST_Origin=$0
Header always set Access-Control-Allow-Origin %{REQUEST_Origin}e env=REQUEST_Origin
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
Header always set Access-Control-Allow-Headers: Authorization
# Force to request 200 for options
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]
Será trabalho 100%, aplicar em .htaccess:
# Enable cross domain access control
SetEnvIf Origin "^http(s)?://(.+\.)?(1xyz\.com|2xyz\.com)$" REQUEST_Origin=$0
Header always set Access-Control-Allow-Origin %{REQUEST_Origin}e env=REQUEST_Origin
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "x-test-header, Origin, X-Requested-With, Content-Type, Accept"
# Force to request 200 for options
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]
Graças a Devin, descobri a solução para o meu aplicativo SLIM com acesso a vários domínios.
No htaccess:
SetEnvIf Origin "http(s)?://(www\.)?(allowed.domain.one|allowed.domain.two)$" AccessControlAllowOrigin=$0$1
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header set Access-Control-Allow-Credentials true
em index.php
// 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, PUT, DELETE, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
// instead of mapping:
$app->options('/(:x+)', function() use ($app) {
//...return correct headers...
$app->response->setStatus(200);
});
Eu tentei a solução @abimelex, mas no Slim 3.0, mapear os pedidos do OPTIONS é como:
$app = new \Slim\App();
$app->options('/books/{id}', function ($request, $response, $args) {
// Return response headers
});
https://www.slimframework.com/docs/objects/router.html#options-route