web-dev-qa-db-pt.com

ativar cors em .htaccess

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?

56
Devin Crossman

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');
77
Devin Crossman

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"
69
markmarijnissen

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"
14
Jack Leon

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>
7
jcubic

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]
6
Santanu Brahma

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]
4
levin

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);
});
2
Karl Adler

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

1
Rocío García Luque