web-dev-qa-db-ja.com

.htaccessでcorsを有効にします

SLIM PHPフレームワークを使用して基本的なRESTfulサービスを作成しましたが、Angular.jsプロジェクトからサービスにアクセスできるように、それを接続しようとしています。 AngularはそのままでCORSをサポートしているので、次の行を追加するだけでした:Header set Access-Control-Allow-Origin "*"を.htaccessファイルに追加しました。

私はこれを実行しましたが、RESTアプリケーションはまだ動作しています(悪い.htaccessからの500内部サーバーエラーはありません)が、 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"

これを適切に機能させるために.htaccessに追加する必要があるものはありますか、またはサーバーでCORSを有効にする別の方法がありますか?

56
Devin Crossman

とにかくすべてをindex.phpに転送していたので、.htaccessファイルの代わりにPHPにヘッダーを設定しようと思ったので、うまくいきました!わーい!この問題を抱えている人のためにindex.phpに追加したものを次に示します。

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

}

クレジットは、 この質問 に対する彼の答えのために斬撃武器になります

Slimを使用しているため、OPTIONS要求がHTTP 200応答を取得するようにこのルートを追加しました

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

.htaccessaddの代わりにsetを使用すべきではありませんか?

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

これは私のために働いたものです:

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

この答えのように 特定のファイルのカスタムHTTPヘッダー<File>を使用して、このコードで単一のファイルのCORSを有効にできます。

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

古いバージョンのslim(2.x)を使用しているようです。次の行を.htaccessに追加するだけで、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

100%動作します。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

Devinのおかげで、マルチドメインアクセスを使用するSLIMアプリケーションのソリューションを見つけました。

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

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

@abimelexソリューションを試しましたが、Slim 3.0では、OPTIONSリクエストのマッピングは次のようになります。

$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