web-dev-qa-db-ja.com

リクエストヘッダフィールドAccess-Control-Allow-Headersは、プリフライトレスポンスでそれ自体では許可されていません

私は何度もCORSの問題に遭遇してきましたが、通常それを修正することができますが、MEANスタックパラダイムからこれを見て本当に理解したいと思います。

これらのことを捕らえるために私のエクスプレスサーバーに単にミドルウェアを追加する前に、それは私の要求を間違っているある種の事前フックがあるように見えます。

要求ヘッダーフィールドAccess-Control-Allow-Headersは、プリフライトレスポンスのAccess-Control-Allow-Headersでは許可されていません

私はこれができると思いました:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers","*")
})

または同等のものですが、これでは解決しないようです。私ももちろん試しました

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers","Access-Control-Allow-Headers")
})

まだ運がありません。

173
mibbit

カスタムリクエストヘッダを試し始めると、CORSプリフライトが得られます。これはHTTPのOPTIONS動詞を使用し、いくつかのヘッダを含むリクエストです。そのうちの1つは、クライアントがリクエストに含めたいヘッダをリストするAccess-Control-Request-Headersです。

これを機能させるには、適切なCORSヘッダを付けてそのCORSプリフライトに返信する必要があります。そのうちの1つは確かにAccess-Control-Allow-Headersです。そのヘッダは、Access-Control-Request-Headersヘッダと同じ(またはそれ以上の)値を含む必要があります。

https://fetch.spec.whatwg.org/#http-cors-protocol この設定についてより詳しく説明しています。

176
Anne

これが機能するために追加する必要があるものです。

    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
    response.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");

ブラウザは、サーバでホストされているサービスが別のドメインのブラウザからアクセスできるかどうかを確認するために、プリフライトリクエスト(メソッドタイプOPTIONS付き)を送信します。上記のヘッダを挿入した場合のプリフライトリクエストへの応答として、ブラウザはそれ以上の呼び出しを行っても問題ないと認識しており、私の実際のGET/POST呼び出しに対して有効な応答が得られます。 *の代わりにAccess-Control-Allow-Origin "、" localhost、xvz.com "を使用して、アクセスが許可されるドメインを制限できます(*はすべてのドメインへのアクセスを許可します)。

84
manish arora

この問題は

 "Origin, X-Requested-With, Content-Type, Accept, Authorization"

私のプロジェクトでは特に(express.js/nodejs)

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
  next();
});

更新:

毎回error:Access-Control-Allow-Headers is not allowed by itself in preflight response errorあなたは chrome開発者ツール :で何が悪いのかを見ることができます
enter image description here

上記のエラーにContent-Typeがないので、Content-Typeに文字列Access-Control-Allow-Headersを追加してください

57
nguyên

受け入れられた答えは大丈夫です、しかし私はそれを理解するのが困難でした。それで、これを明確にする簡単な例です。

私のajaxリクエストには標準のAuthorizationヘッダがありました。

    $$(document).on('ajaxStart', function(e){
    var auth_token = localStorage.getItem(SB_TOKEN_MOBILE);
    if( auth_token ) {
        var xhr = e.detail.xhr;

        xhr.setRequestHeader('**Authorization**', 'Bearer ' + auth_token);
    }

このコードは問題のエラーを生成します。私のnodejsサーバーでしなければならなかったのは、許可ヘッダーにAuthorizationを追加することでした。

res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,**Authorization**');
14
user732456

他の答えに追加する。私は同じ問題を抱えており、これは私が私のエクスプレスサーバーでREST呼び出しを許可するために使用したコードです:

  app.all('*', function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'URLs to trust of allow');
    res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    if ('OPTIONS' == req.method) {
    res.sendStatus(200);
    } else {
      next();
    }
  });

このコードが基本的にしていることはすべてのリクエストを傍受してCORSヘッダを追加し、それから私の通常のルートを続けることです。 OPTIONS要求があると、それはCORSヘッダーでのみ応答します。

編集:私は同じマシン上の2つの別々のnodejsエクスプレスサーバーにこの修正プログラムを使用していました。最後に、私は単純なプロキシサーバーに関する問題を修正しました。

6
Luke Kroon

私はこの問題に遭遇したばかりです。ASP.NETのコンテキストでは、Web.configがこのようになっていることを確認してください。

  <system.webServer>
<modules>
  <remove name="FormsAuthentication" />
</modules>

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <!--<remove name="OPTIONSVerbHandler"/>-->
  <remove name="TRACEVerbHandler" />
  <!--
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  -->
</handlers>

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
  </customHeaders>
</httpProtocol>

Access-Control-Allow-HeadersキーのAuthorization値に注目してください。 Authorizationの値が足りないのですが、この設定で問題が解決します。

5
Josh Siegl

とても良い私はsilexプロジェクトでこれを使った

$app->after(function (Request $request, Response $response) {
        $response->headers->set('Access-Control-Allow-Origin', '*');
        $response->headers->set("Access-Control-Allow-Credentials", "true");
        $response->headers->set("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
        $response->headers->set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
    });
5
Al Kativo

Chromeの場合:

リクエストヘッダフィールドX-Requested-Withは、プリフライトレスポンスのAccess-Control-Allow-Headersでは許可されていません。

私にとっては、このエラーは この呼び出しのURLの末尾のスペース によって引き起こされました。

jQuery.getJSON( url, function( response, status, xhr ) {
   ...
}
3
user3248255

それを付け加えると、あなたはそれらのヘッダをWebpackの設定ファイルにも置くことができます。私はwebpack devサーバーを実行していたので私の場合のように私はそれらを必要としていました。

devServer: {
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Credentials": "true",
      "Access-Control-Allow-Methods": "GET,HEAD,OPTIONS,POST,PUT",
      "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Authorization"
},
2
Janne

この問題はrequest.Thisのカスタムヘッダーを作成するときに発生します。このリクエストはHTTP OPTIONSを使用し、いくつかのヘッダーを含みます。

このリクエストに必要なヘッダはAccess-Control-Request-Headersです。これはレスポンスヘッダの一部であり、すべてのOriginからのリクエストを許可する必要があります。レスポンスのヘッダにもContent-Typeが必要な場合があります。それであなたのレスポンスヘッダはそのようなものであるべきです -

 response.header("Access-Control-Allow-Origin", "*"); // allow request from all Origin
  response.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
  response.header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Authorization");
2
Sai prateek

ほぼ一日を過ごした後、私はちょうど以下の2つのコードを追加することが私の問題を解決することを知りました。

Global.asaxにこれを追加

  protected void Application_BeginRequest()
    {
        if (Request.HttpMethod == "OPTIONS")
        {
            Response.StatusCode = (int)System.Net.HttpStatusCode.OK;             
            Response.End();
        }
    }

そしてWeb設定で以下を追加してください

 <httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />        
    <add name="Access-Control-Allow-Methods" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
  </customHeaders>

</httpProtocol>
1
Biruk Belihu

OPがDjango、React、およびDjango-cors-headers libを使用して記述したエラーを受け取りました。このスタックで修正するには、次の手順に従います。

Settings.pyに 公式ドキュメント に従って以下を追加してください。

from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = default_headers + (
'YOUR_HEADER_NAME',
)
1
Eric

res.setHeader( 'Access-Control-Allow-Headers'、 '*');

1
KANOMDOOK

Post API呼び出しでは、リクエスト本文でデータを送信しています。したがって、API呼び出しに追加のヘッダーを追加してデータを送信する場合。次に、最初のOPTIONS API呼び出しが行われ、次にポスト呼び出しが行われます。したがって、最初にOPTION API呼び出しを処理する必要があります。

問題を処理するには、フィルターを作成し、その内部でオプション呼び出しAPI呼び出しを確認し、200 OKステータスを返す必要があります。以下にサンプルコードを示します。

package com.web.filter;

import Java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.Apache.catalina.connector.Response;

public class CustomFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest httpRequest = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type");
        if (httpRequest.getMethod().equalsIgnoreCase("OPTIONS")) {
            response.setStatus(Response.SC_OK);
        }
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {
        // TODO
    }

    public void destroy() {
        // Todo
    }

}
1
user11815301

私もAngular 6で同じ問題に直面しました。私は以下のコードを使用して問題を解決しました。

Add the code in component.ts file.

    import { HttpHeaders } from '@angular/common/http';

    headers;

    constructor() {
        this.headers = new HttpHeaders();
        this.headers.append('Access-Control-Allow-Headers', 'Authorization');
    }

    getData() {
        this.http.get(url,this.headers). subscribe (res => {
    your code here...

    })

}
0

私が直面していたのと同じ問題。

私は簡単な変更をしました。

  <modulename>.config(function($httpProvider){
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
0

APIで '認証'が許可されていないことを示すメッセージがはっきりしています。セット
Access-Control-Allow-Headers: "コンテンツタイプ、承認"

0
Rajesh Yadav