在.htaccess 中启用 cors

我已经用 SLIM PHP 框架创建了一个基本的 RESTful 服务,现在我尝试将它连接起来,以便能够从 Angular.js 项目访问该服务。我已经读到,角度支持 CORS 开箱即用,所有我需要做的是添加这一行: Header set Access-Control-Allow-Origin "*"到我的。Htaccess 文件。

我已经这样做了,我的 REST 应用程序仍然在工作(没有500个内部服务器错误从一个坏。Htaccess) ,但是当我试图从 Test-cors.org测试它时,它抛出了一个错误。

Fired XHR event: loadstart
Fired XHR event: readystatechange
Fired XHR event: error


XHR status: 0
XHR status text:
Fired XHR event: loadend

我的.htaccess 文件如下所示

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"

还有什么要补充的吗。是否有其他方法在我的服务器上启用 CORS?

231638 次浏览

Since I had everything being forwarded to index.php anyway I thought I would try setting the headers in PHP instead of the .htaccess file and it worked! YAY! Here's what I added to index.php for anyone else having this problem.

// 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']}");


}

credit goes to slashingweapon for his answer on this question

Because I'm using Slim I added this route so that OPTIONS requests get a HTTP 200 response

// return HTTP 200 for HTTP OPTIONS requests
$app->map('/:x+', function($x) {
http_response_code(200);
})->via('OPTIONS');

Should't the .htaccess use add instead of set?

Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"

Thanks to Devin, I figured out the solution for my SLIM application with multi domain access.

In 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

in 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);
});

This is what worked for me:

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"

It's look like you are using an old version of slim(2.x). You can just add following lines to .htaccess and don't need to do anything in PHP scripts.

# 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]

I tried @abimelex solution, but in Slim 3.0, mapping the OPTIONS requests goes like:

$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

As in this answer Custom HTTP Header for a specific file you can use <File> to enable CORS for a single file with this code:

<Files "index.php">
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
</Files>

Instead of "*" you can put specific origin (protocol + domain+ optional port).

Will be work 100%, Apply in .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]

For ubuntu users:

You have to activate first the headers module by using the following command:

sudo a2enmod headers

Then restart apache by:

sudo service apache2 restart

Then add the following headers to your htaccess:

Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header set Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"