Povolit žádosti mezi zdroji (CORS) v ASP.NET CoreEnable Cross-Origin Requests (CORS) in ASP.NET Core

Autor: Rick AndersonBy Rick Anderson

Tento článek popisuje, jak v aplikaci ASP.NET Core povolit CORS.This article shows how to enable CORS in an ASP.NET Core app.

Zabezpečení prohlížeče brání webové stránce v tom, aby prováděla požadavky na jinou doménu než ta, která tuto webovou stránku obsluhoval.Browser security prevents a web page from making requests to a different domain than the one that served the web page. Toto omezení se nazývá zásady stejného původu.This restriction is called the same-origin policy. Zásady stejného původce brání škodlivému webu v čtení citlivých dat z jiné lokality.The same-origin policy prevents a malicious site from reading sensitive data from another site. V některých případech můžete chtít, aby ostatní weby ve vaší aplikaci provedly žádosti o více zdrojů.Sometimes, you might want to allow other sites make cross-origin requests to your app. Další informace najdete v článku věnovaném Mozilla CORS.For more information, see the Mozilla CORS article.

Sdílení prostředků mezi zdroji (CORS):Cross Origin Resource Sharing (CORS):

  • Je standard W3C, který umožňuje serveru zmírnit zásady stejného zdroje.Is a W3C standard that allows a server to relax the same-origin policy.
  • Nejedná se o funkci zabezpečení, CORS zabezpečení CORS zmírnit.Is not a security feature, CORS relaxes security. Rozhraní API není bezpečnější díky povolení CORS.An API is not safer by allowing CORS. Další informace najdete v tématu jak CORS funguje.For more information, see How CORS works.
  • Umožňuje serveru explicitně povolit některé žádosti mezi zdroji a současně odmítat jiné.Allows a server to explicitly allow some cross-origin requests while rejecting others.
  • Je bezpečnější a pružnější než u předchozích technik, jako třeba JSONP.Is safer and more flexible than earlier techniques, such as JSONP.

Zobrazit nebo stáhnout ukázkový kód (Jak stáhnout)View or download sample code (how to download)

Stejný původSame origin

Dvě adresy URL mají stejný původ, pokud mají identická schémata, hostitele a porty (RFC 6454).Two URLs have the same origin if they have identical schemes, hosts, and ports (RFC 6454).

Tyto dvě adresy URL mají stejný původ:These two URLs have the same origin:

  • https://example.com/foo.html
  • https://example.com/bar.html

Tyto adresy URL mají různé zdroje, než jsou předchozí dvě adresy URL:These URLs have different origins than the previous two URLs:

  • https://example.net – jiné doméněhttps://example.net – Different domain
  • https://www.example.com/foo.html – různé subdoményhttps://www.example.com/foo.html – Different subdomain
  • http://example.com/foo.html – různých schémathttp://example.com/foo.html – Different scheme
  • https://example.com:9000/foo.html – jiný porthttps://example.com:9000/foo.html – Different port

Internet Explorer při porovnávání zdrojů nebere v úvahu port.Internet Explorer doesn't consider the port when comparing origins.

CORS s pojmenovanými zásadami a middlewaremCORS with named policy and middleware

Middleware CORS zpracovává požadavky mezi zdroji.CORS Middleware handles cross-origin requests. Následující kód umožňuje CORS pro celou aplikaci se zadaným počátkem:The following code enables CORS for the entire app with the specified origin:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(MyAllowSpecificOrigins,
            builder =>
            {
                builder.WithOrigins("http://example.com",
                                    "http://www.contoso.com");
            });
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseCors(MyAllowSpecificOrigins); 

        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

Předchozí kód:The preceding code:

Volání metody AddCors přidá služby CORS do kontejneru služby aplikace:The AddCors method call adds CORS services to the app's service container:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy(MyAllowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("http://example.com",
                                "http://www.contoso.com");
        });
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Další informace najdete v tématu Možnosti zásad CORS v tomto dokumentu.For more information, see CORS policy options in this document .

Metoda CorsPolicyBuilder může řetězit metody, jak je znázorněno v následujícím kódu:The CorsPolicyBuilder method can chain methods, as shown in the following code:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy(MyAllowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("http://example.com",
                                "http://www.contoso.com")
                                .AllowAnyHeader()
                                .AllowAnyMethod();
        });
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Poznámka: adresa URL nesmí obsahovat koncové lomítko (/).Note: The URL must not contain a trailing slash (/). Pokud se adresa URL ukončí s /, porovnávání vrátí false a nevrátí se žádné záhlaví.If the URL terminates with /, the comparison returns false and no header is returned.

Použití zásad CORS u všech koncových bodůApply CORS policies to all endpoints

Následující kód aplikuje zásady CORS na všechny koncové body aplikací prostřednictvím middlewaru CORS:The following code applies CORS policies to all the apps endpoints via CORS Middleware:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // Preceding code ommitted.
    app.UseRouting();

    app.UseCors();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

    // Following code ommited.
}

Upozornění

Při směrování koncových bodů musí být middleware CORS nakonfigurované tak, aby se spouštěla mezi voláními UseRouting a UseEndpoints.With endpoint routing, the CORS middleware must be configured to execute between the calls to UseRouting and UseEndpoints. Nesprávná konfigurace způsobí, že middleware přestane fungovat správně.Incorrect configuration will cause the middleware to stop functioning correctly.

Následující kód aplikuje zásady CORS na všechny koncové body aplikací prostřednictvím middlewaru CORS:The following code applies CORS policies to all the apps endpoints via CORS Middleware:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    app.UseCors();

    app.UseHttpsRedirection();
    app.UseMvc();
}

Poznámka: před UseMvcje nutné volat UseCors.Note: UseCors must be called before UseMvc.

Viz Povolení CORS v Razor Pages, řadičích a metodách akcí pro aplikování zásad CORS na úrovni stránky, řadiče nebo akce.See Enable CORS in Razor Pages, controllers, and action methods to apply CORS policy at the page/controller/action level.

Pokyny k testování předchozího kódu najdete v části test CORS .See Test CORS for instructions on testing the preceding code.

Povolení CORS s směrováním koncových bodůEnable Cors with endpoint routing

S směrováním koncových bodů je možné CORS povolit na základě jednotlivých koncových bodů pomocí RequireCors sady rozšiřujících metod.With endpoint routing, CORS can be enabled on a per-endpoint basis using the RequireCors set of extension methods.

app.UseEndpoints(endpoints =>
{
  endpoints.MapGet("/echo", async context => context.Response.WriteAsync("echo"))
    .RequireCors("policy-name");
});

Podobně lze CORS povolit také pro všechny řadiče:Similarly, CORS can also be enabled for all controllers:

app.UseEndpoints(endpoints =>
{
  endpoints.MapControllers().RequireCors("policy-name");
});

Povolení CORS s atributyEnable CORS with attributes

Atribut [EnableCors] poskytuje alternativu k použití CORS globálně.The [EnableCors] attribute provides an alternative to applying CORS globally. Atribut [EnableCors] povoluje CORS pro vybrané koncové body místo všech koncových bodů.The [EnableCors] attribute enables CORS for selected end points, rather than all end points.

Pomocí [EnableCors] můžete zadat výchozí zásady a [EnableCors("{Policy String}")] zadat zásadu.Use [EnableCors] to specify the default policy and [EnableCors("{Policy String}")] to specify a policy.

Atribut [EnableCors] lze použít pro:The [EnableCors] attribute can be applied to:

  • PageModel stránky RazorRazor Page PageModel
  • KontrolérController
  • Metoda akce kontroleruController action method

Pomocí atributu [EnableCors] můžete použít různé zásady na řadič nebo stránku-model/akce.You can apply different policies to controller/page-model/action with the [EnableCors] attribute. Pokud je atribut [EnableCors] aplikován na řadiče/stránky – model/akce a v middleware je povolená CORS, uplatní se obě zásady.When the [EnableCors] attribute is applied to a controllers/page-model/action method, and CORS is enabled in middleware, both policies are applied. Doporučujeme před kombinováním zásad.We recommend against combining policies. Použijte atribut [EnableCors] nebo middleware, nikoli oba ve stejné aplikaci.Use the [EnableCors] attribute or middleware, not both in the same app.

Následující kód používá pro každou metodu jinou zásadu:The following code applies a different policy to each method:

[Route("api/[controller]")]
[ApiController]
public class WidgetController : ControllerBase
{
    // GET api/values
    [EnableCors("AnotherPolicy")]
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "green widget", "red widget" };
    }

    // GET api/values/5
    [EnableCors]        // Default policy.
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        switch (id)
        {
            case 1:
                return "green widget";
            case 2:
                return "red widget";
            default:
                return NotFound();
        }
    }
}

Následující kód vytvoří výchozí zásadu CORS a zásadu s názvem "AnotherPolicy":The following code creates a CORS default policy and a policy named "AnotherPolicy":

public class StartupMultiPolicy
{
    public StartupMultiPolicy(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddDefaultPolicy(
                builder =>
                {
                   
                    builder.WithOrigins("http://example.com",
                                        "http://www.contoso.com");
                });

            options.AddPolicy("AnotherPolicy",
                builder =>
                {
                    builder.WithOrigins("http://www.contoso.com")
                                        .AllowAnyHeader()
                                        .AllowAnyMethod();
                });

        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

Zakázání CORSDisable CORS

Atribut [DisableCors] zakáže CORS pro kontroler/Page-model/Action.The [DisableCors] attribute disables CORS for the controller/page-model/action.

Možnosti zásad CORSCORS policy options

Tato část popisuje různé možnosti, které je možné nastavit v zásadách CORS:This section describes the various options that can be set in a CORS policy:

AddPolicy se volá v Startup.ConfigureServices.AddPolicy is called in Startup.ConfigureServices. U některých možností může být užitečné si nejdřív přečíst oddíl jak CORS funguje .For some options, it may be helpful to read the How CORS works section first.

Nastavení povolených zdrojůSet the allowed origins

AllowAnyOrigin – povoluje žádosti CORS ze všech míst původu s jakýmkoli schématem (http nebo https).AllowAnyOrigin – Allows CORS requests from all origins with any scheme (http or https). AllowAnyOrigin je nezabezpečený, protože libovolný web může do aplikace dělat žádosti mezi zdroji.AllowAnyOrigin is insecure because any website can make cross-origin requests to the app.

Poznámka

Zadání AllowAnyOrigin a AllowCredentials je nezabezpečená konfigurace a může vést k padělání požadavků mezi lokalitami.Specifying AllowAnyOrigin and AllowCredentials is an insecure configuration and can result in cross-site request forgery. Služba CORS vrátí neplatnou odpověď CORS, pokud je aplikace nakonfigurovaná pomocí obou metod.The CORS service returns an invalid CORS response when an app is configured with both methods.

Poznámka

Zadání AllowAnyOrigin a AllowCredentials je nezabezpečená konfigurace a může vést k padělání požadavků mezi lokalitami.Specifying AllowAnyOrigin and AllowCredentials is an insecure configuration and can result in cross-site request forgery. V případě zabezpečené aplikace zadejte přesný seznam zdrojů, pokud je klient musí autorizovat pro přístup k prostředkům serveru.For a secure app, specify an exact list of origins if the client must authorize itself to access server resources.

AllowAnyOrigin má vliv na požadavky na kontrolu a Access-Control-Allow-Origin hlavičku.AllowAnyOrigin affects preflight requests and the Access-Control-Allow-Origin header. Další informace najdete v části požadavky na kontrolu před výstupem .For more information, see the Preflight requests section.

SetIsOriginAllowedToAllowWildcardSubdomains – nastaví vlastnost IsOriginAllowed zásady tak, aby byla funkce, která umožňuje, aby se zdroje shodovaly s konfigurovanou doménou se zástupnými znaky při vyhodnocování, jestli je původ povolený.SetIsOriginAllowedToAllowWildcardSubdomains – Sets the IsOriginAllowed property of the policy to be a function that allows origins to match a configured wildcard domain when evaluating if the origin is allowed.

options.AddPolicy("AllowSubdomain",
    builder =>
    {
        builder.WithOrigins("https://*.example.com")
            .SetIsOriginAllowedToAllowWildcardSubdomains();
    });

Nastavení povolených metod HTTPSet the allowed HTTP methods

AllowAnyMethod:AllowAnyMethod:

  • Umožňuje jakoukoli metodu HTTP:Allows any HTTP method:
  • Má vliv na požadavky na kontrolu a Access-Control-Allow-Methods hlavičku.Affects preflight requests and the Access-Control-Allow-Methods header. Další informace najdete v části požadavky na kontrolu před výstupem .For more information, see the Preflight requests section.

Nastavení povolených hlaviček žádostiSet the allowed request headers

Chcete-li povolit odeslání konkrétních hlaviček v žádosti CORS s názvem záhlaví žádosti o autora, zavolejte WithHeaders a zadejte povolené hlavičky:To allow specific headers to be sent in a CORS request, called author request headers, call WithHeaders and specify the allowed headers:

options.AddPolicy("AllowHeaders",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .WithHeaders(HeaderNames.ContentType, "x-custom-header");
    });

Chcete-li povolení všech hlaviček žádostí o autora, zavolejte AllowAnyHeader:To allow all author request headers, call AllowAnyHeader:

options.AddPolicy("AllowAllHeaders",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .AllowAnyHeader();
    });

Toto nastavení má vliv na žádosti o kontrolu a Access-Control-Request-Headers hlavičku.This setting affects preflight requests and the Access-Control-Request-Headers header. Další informace najdete v části požadavky na kontrolu před výstupem .For more information, see the Preflight requests section.

Zásada middlewaru CORS odpovídá konkrétním hlavičkám určeným WithHeaders je možné pouze v případě, že hlavičky odeslané Access-Control-Request-Headers přesně odpovídají hlavičkám uvedeným v WithHeaders.A CORS Middleware policy match to specific headers specified by WithHeaders is only possible when the headers sent in Access-Control-Request-Headers exactly match the headers stated in WithHeaders.

Představte si například aplikaci nakonfigurovanou takto:For instance, consider an app configured as follows:

app.UseCors(policy => policy.WithHeaders(HeaderNames.CacheControl));

Middleware CORS odmítá požadavek na kontrolu před výstupem s následující hlavičkou požadavku, protože Content-Language (HeaderNames. ContentLanguage) není uveden v WithHeaders:CORS Middleware declines a preflight request with the following request header because Content-Language (HeaderNames.ContentLanguage) isn't listed in WithHeaders:

Access-Control-Request-Headers: Cache-Control, Content-Language

Aplikace vrátí odpověď 200 OK , ale nepošle hlavičky CORS zpátky.The app returns a 200 OK response but doesn't send the CORS headers back. Proto prohlížeč nezkouší požadavek mezi zdroji.Therefore, the browser doesn't attempt the cross-origin request.

Middleware CORS vždycky povoluje posílání čtyř hlaviček v Access-Control-Request-Headers bez ohledu na hodnoty nakonfigurované v CorsPolicy. Headers.CORS Middleware always allows four headers in the Access-Control-Request-Headers to be sent regardless of the values configured in CorsPolicy.Headers. Tento seznam hlaviček obsahuje:This list of headers includes:

  • Accept
  • Accept-Language
  • Content-Language
  • Origin

Představte si například aplikaci nakonfigurovanou takto:For instance, consider an app configured as follows:

app.UseCors(policy => policy.WithHeaders(HeaderNames.CacheControl));

Middleware CORS odpoví úspěšně do žádosti o kontrolu před výstupem s následující hlavičkou požadavku, protože Content-Language je vždy na seznamu povolených:CORS Middleware responds successfully to a preflight request with the following request header because Content-Language is always whitelisted:

Access-Control-Request-Headers: Cache-Control, Content-Language

Nastavení hlaviček vystavené odpovědiSet the exposed response headers

Ve výchozím nastavení prohlížeč nezveřejňuje všechny hlavičky odpovědí do aplikace.By default, the browser doesn't expose all of the response headers to the app. Další informace najdete v tématu sdílení prostředků mezi zdroji W3C (terminologie): jednoduchá hlavička odpovědi.For more information, see W3C Cross-Origin Resource Sharing (Terminology): Simple Response Header.

Ve výchozím nastavení jsou k dispozici následující hlavičky odpovědí:The response headers that are available by default are:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

Specifikace CORS volá tyto hlavičky jednoduché hlavičky odpovědi.The CORS specification calls these headers simple response headers. K zpřístupnění dalších hlaviček pro aplikaci volejte WithExposedHeaders:To make other headers available to the app, call WithExposedHeaders:

options.AddPolicy("ExposeResponseHeaders",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .WithExposedHeaders("x-custom-header");
    });

Přihlašovací údaje v žádostech mezi zdrojiCredentials in cross-origin requests

Přihlašovací údaje vyžadují zvláštní zpracování v žádosti CORS.Credentials require special handling in a CORS request. V prohlížeči se ve výchozím nastavení neodesílají přihlašovací údaje s žádostí o více zdrojů.By default, the browser doesn't send credentials with a cross-origin request. Přihlašovací údaje zahrnují soubory cookie a schémata ověřování HTTP.Credentials include cookies and HTTP authentication schemes. Aby bylo možné odesílat přihlašovací údaje pomocí žádosti o více zdrojů, musí klient nastavit XMLHttpRequest.withCredentials true.To send credentials with a cross-origin request, the client must set XMLHttpRequest.withCredentials to true.

Přímé použití XMLHttpRequest:Using XMLHttpRequest directly:

var xhr = new XMLHttpRequest();
xhr.open('get', 'https://www.example.com/api/test');
xhr.withCredentials = true;

Pomocí jQuery:Using jQuery:

$.ajax({
  type: 'get',
  url: 'https://www.example.com/api/test',
  xhrFields: {
    withCredentials: true
  }
});

Pomocí rozhraní API pro načtení:Using the Fetch API:

fetch('https://www.example.com/api/test', {
    credentials: 'include'
});

Server musí přihlašovací údaje umožňovat.The server must allow the credentials. Pokud chcete povolení přihlašovacích údajů pro více zdrojů, zavolejte AllowCredentials:To allow cross-origin credentials, call AllowCredentials:

options.AddPolicy("AllowCredentials",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .AllowCredentials();
    });

Odpověď HTTP obsahuje hlavičku Access-Control-Allow-Credentials, která oznamuje prohlížeči, že server povoluje přihlašovací údaje pro požadavek mezi zdroji.The HTTP response includes an Access-Control-Allow-Credentials header, which tells the browser that the server allows credentials for a cross-origin request.

Pokud prohlížeč odesílá přihlašovací údaje, ale odpověď neobsahuje platnou hlavičku Access-Control-Allow-Credentials, prohlížeč nezveřejňuje odpověď na aplikaci a žádost o více zdrojů se nezdařila.If the browser sends credentials but the response doesn't include a valid Access-Control-Allow-Credentials header, the browser doesn't expose the response to the app, and the cross-origin request fails.

Povolení přihlašovacích údajů mezi zdroji je bezpečnostní riziko.Allowing cross-origin credentials is a security risk. Web v jiné doméně může odeslat přihlašovací údaje přihlášeného uživatele do aplikace jménem uživatele bez vědomí uživatele.A website at another domain can send a signed-in user's credentials to the app on the user's behalf without the user's knowledge.

Specifikace CORS také uvádí, že nastavení původes na "*" (všechny zdroje) je neplatné, pokud je k dispozici Access-Control-Allow-Credentials záhlaví.The CORS specification also states that setting origins to "*" (all origins) is invalid if the Access-Control-Allow-Credentials header is present.

Požadavky na kontrolu před výstupemPreflight requests

U některých požadavků CORS prohlížeč před provedením samotného požadavku pošle další požadavek.For some CORS requests, the browser sends an additional request before making the actual request. Tento požadavek se nazývá žádost o kontrolu před výstupem.This request is called a preflight request. Prohlížeč může požadavek na předběžné kontroly přeskočit, pokud jsou splněné následující podmínky:The browser can skip the preflight request if the following conditions are true:

  • Metoda Request je GET, HEAD nebo POST.The request method is GET, HEAD, or POST.
  • Aplikace nenastaví záhlaví žádostí kromě Accept, Accept-Language, Content-Language, Content-Typenebo Last-Event-ID.The app doesn't set request headers other than Accept, Accept-Language, Content-Language, Content-Type, or Last-Event-ID.
  • Content-Type záhlaví, pokud je nastaveno, má jednu z následujících hodnot:The Content-Type header, if set, has one of the following values:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

Pravidlo pro záhlaví požadavku nastavené pro požadavek klienta se vztahuje na hlavičky, které sada App Sets nastaví voláním setRequestHeader na objektu XMLHttpRequest.The rule on request headers set for the client request applies to headers that the app sets by calling setRequestHeader on the XMLHttpRequest object. Specifikace CORS volá záhlaví požadavku autorazáhlaví.The CORS specification calls these headers author request headers. Toto pravidlo se nevztahuje na záhlaví, která může prohlížeč nastavit, například User-Agent, Hostnebo Content-Length.The rule doesn't apply to headers the browser can set, such as User-Agent, Host, or Content-Length.

Následuje příklad žádosti o kontrolu před výstupem:The following is an example of a preflight request:

OPTIONS https://myservice.azurewebsites.net/api/test HTTP/1.1
Accept: */*
Origin: https://myclient.azurewebsites.net
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: accept, x-my-custom-header
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: myservice.azurewebsites.net
Content-Length: 0

Požadavek na lety používá metodu HTTP.The pre-flight request uses the HTTP OPTIONS method. Obsahuje dvě speciální hlavičky:It includes two special headers:

  • Access-Control-Request-Method: metoda HTTP, která se bude používat pro skutečný požadavek.Access-Control-Request-Method: The HTTP method that will be used for the actual request.
  • Access-Control-Request-Headers: seznam hlaviček požadavků, které aplikace nastaví na skutečném požadavku.Access-Control-Request-Headers: A list of request headers that the app sets on the actual request. Jak bylo uvedeno výše, nezahrnuje hlavičky, které prohlížeč nastavuje, například User-Agent.As stated earlier, this doesn't include headers that the browser sets, such as User-Agent.

Požadavek předběžné kontroly CORS může zahrnovat hlavičku Access-Control-Request-Headers, která serveru oznamuje hlavičkám, které jsou odesílány se skutečným požadavkem.A CORS preflight request might include an Access-Control-Request-Headers header, which indicates to the server the headers that are sent with the actual request.

Pro povolení konkrétních hlaviček volejte WithHeaders:To allow specific headers, call WithHeaders:

options.AddPolicy("AllowHeaders",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .WithHeaders(HeaderNames.ContentType, "x-custom-header");
    });

Chcete-li povolení všech hlaviček žádostí o autora, zavolejte AllowAnyHeader:To allow all author request headers, call AllowAnyHeader:

options.AddPolicy("AllowAllHeaders",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .AllowAnyHeader();
    });

Prohlížeče nejsou zcela konzistentní v tom, jak nastavují Access-Control-Request-Headers.Browsers aren't entirely consistent in how they set Access-Control-Request-Headers. Pokud jste nastavili záhlaví na jinou hodnotu než "*" (nebo používáte AllowAnyHeader), měli byste zahrnout alespoň Accept, Content-Typea Origina také všechna vlastní záhlaví, která chcete podporovat.If you set headers to anything other than "*" (or use AllowAnyHeader), you should include at least Accept, Content-Type, and Origin, plus any custom headers that you want to support.

Následuje příklad odpovědi na žádost o kontrolu před výstupem (za předpokladu, že server povoluje požadavek):The following is an example response to the preflight request (assuming that the server allows the request):

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 0
Access-Control-Allow-Origin: https://myclient.azurewebsites.net
Access-Control-Allow-Headers: x-my-custom-header
Access-Control-Allow-Methods: PUT
Date: Wed, 20 May 2015 06:33:22 GMT

Odpověď obsahuje Access-Control-Allow-Methods záhlaví, ve kterém jsou uvedeny povolené metody a volitelně Access-Control-Allow-Headers záhlaví, které obsahuje seznam povolených hlaviček.The response includes an Access-Control-Allow-Methods header that lists the allowed methods and optionally an Access-Control-Allow-Headers header, which lists the allowed headers. Pokud je žádost o kontrolu před výstupem úspěšná, prohlížeč pošle skutečný požadavek.If the preflight request succeeds, the browser sends the actual request.

Pokud je žádost o předběžné kontroly zamítnutá, aplikace vrátí odpověď 200 OK , ale nepošle hlavičky CORS zpátky.If the preflight request is denied, the app returns a 200 OK response but doesn't send the CORS headers back. Proto prohlížeč nezkouší požadavek mezi zdroji.Therefore, the browser doesn't attempt the cross-origin request.

Nastavit čas vypršení platnosti předběžné kontrolySet the preflight expiration time

Hlavička Access-Control-Max-Age určuje, jak dlouho může být odpověď na požadavek na kontrolu před výstupem ukládána do mezipaměti.The Access-Control-Max-Age header specifies how long the response to the preflight request can be cached. Chcete-li nastavit tuto hlavičku, zavolejte SetPreflightMaxAge:To set this header, call SetPreflightMaxAge:

options.AddPolicy("SetPreflightExpiration",
    builder =>
    {
        builder.WithOrigins("http://example.com")
               .SetPreflightMaxAge(TimeSpan.FromSeconds(2520));
    });

Jak CORS fungujeHow CORS works

Tato část popisuje, co se stane v žádosti CORS na úrovni zpráv HTTP.This section describes what happens in a CORS request at the level of the HTTP messages.

  • CORS není funkce zabezpečení.CORS is not a security feature. CORS je standard W3C, který umožňuje serveru zmírnit zásady stejného zdroje.CORS is a W3C standard that allows a server to relax the same-origin policy.
    • Škodlivý objekt actor by například mohl použít možnost zabránit skriptování mezi weby (XSS) na vašem webu a provést požadavek napříč lokalitami na lokalitu s povoleným CORS, aby mohl ukrást informace.For example, a malicious actor could use Prevent Cross-Site Scripting (XSS) against your site and execute a cross-site request to their CORS enabled site to steal information.
  • Vaše rozhraní API není bezpečnější díky povolení CORS.Your API is not safer by allowing CORS.
    • Pro vymáhání CORS je to až klient (prohlížeč).It's up to the client (browser) to enforce CORS. Server požadavek spustí a vrátí odpověď, jedná se o klienta, který vrátí chybu a zablokuje odpověď.The server executes the request and returns the response, it's the client that returns an error and blocks the response. Například kterýkoli z následujících nástrojů zobrazí odpověď serveru:For example, any of the following tools will display the server response:
  • To je způsob, jak serveru dovolit prohlížečům spustit XHR nebo načíst požadavek rozhraní API pro různé zdroje, které by jinak bylo zakázané.It's a way for a server to allow browsers to execute a cross-origin XHR or Fetch API request that otherwise would be forbidden.
    • Prohlížeče (bez CORS) nemůžou provádět žádosti mezi zdroji.Browsers (without CORS) can't do cross-origin requests. Před CORS se k obcházení tohoto omezení použil JSONP .Before CORS, JSONP was used to circumvent this restriction. JSONP nepoužívá XHR, používá značku <script> k přijetí odpovědi.JSONP doesn't use XHR, it uses the <script> tag to receive the response. Skripty mohou být načteny mezi zdroji.Scripts are allowed to be loaded cross-origin.

Specifikace CORS představila několik nových hlaviček protokolu HTTP, které umožňují žádosti mezi zdroji.The CORS specification introduced several new HTTP headers that enable cross-origin requests. Pokud prohlížeč podporuje CORS, nastaví tyto hlavičky pro žádosti mezi zdroji automaticky.If a browser supports CORS, it sets these headers automatically for cross-origin requests. Pro povolení CORS není nutný vlastní kód JavaScriptu.Custom JavaScript code isn't required to enable CORS.

Následuje příklad žádosti o více zdrojů.The following is an example of a cross-origin request. Hlavička Origin poskytuje doménu lokality, ze které se vytváří požadavek.The Origin header provides the domain of the site that's making the request. Hlavička Origin je povinná a musí se lišit od hostitele.The Origin header is required and must be different from the host.

GET https://myservice.azurewebsites.net/api/test HTTP/1.1
Referer: https://myclient.azurewebsites.net/
Accept: */*
Accept-Language: en-US
Origin: https://myclient.azurewebsites.net
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: myservice.azurewebsites.net

Pokud server tuto žádost povoluje, nastaví v odpovědi hlavičku Access-Control-Allow-Origin.If the server allows the request, it sets the Access-Control-Allow-Origin header in the response. Hodnota této hlavičky se buď shoduje s hlavičkou Origin z požadavku, nebo se jedná o zástupnou hodnotu "*", což znamená, že je povolený libovolný původ:The value of this header either matches the Origin header from the request or is the wildcard value "*", meaning that any origin is allowed:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/plain; charset=utf-8
Access-Control-Allow-Origin: https://myclient.azurewebsites.net
Date: Wed, 20 May 2015 06:27:30 GMT
Content-Length: 12

Test message

Pokud odpověď neobsahuje hlavičku Access-Control-Allow-Origin, požadavek na více zdrojů se nezdařil.If the response doesn't include the Access-Control-Allow-Origin header, the cross-origin request fails. Konkrétně prohlížeč požadavek nepovoluje.Specifically, the browser disallows the request. I v případě, že server vrátí úspěšnou odpověď, prohlížeč nezpřístupňuje odpověď klientské aplikaci.Even if the server returns a successful response, the browser doesn't make the response available to the client app.

Test CORSTest CORS

Testování CORS:To test CORS:

  1. Vytvořte projekt API.Create an API project. Alternativně si můžete Stáhnout ukázku.Alternatively, you can download the sample.
  2. Povolte CORS pomocí jednoho z přístupů v tomto dokumentu.Enable CORS using one of the approaches in this document. Například:For example:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    // Shows UseCors with CorsPolicyBuilder.
    app.UseCors(builder =>
    {
        builder.WithOrigins("http://example.com",
                            "http://www.contoso.com",
                            "https://localhost:44375",
                            "https://localhost:5001");
    });

    app.UseHttpsRedirection();
    app.UseMvc();
}

Upozornění

WithOrigins("https://localhost:<port>"); by se měla použít jenom pro testování ukázkové aplikace podobné ukázkovému kódu ke stažení.WithOrigins("https://localhost:<port>"); should only be used for testing a sample app similar to the download sample code.

  1. Vytvořte projekt webové aplikace (Razor Pages nebo MVC).Create a web app project (Razor Pages or MVC). Ukázka používá Razor Pages.The sample uses Razor Pages. Webovou aplikaci můžete vytvořit ve stejném řešení jako projekt rozhraní API.You can create the web app in the same solution as the API project.
  2. Do souboru index. cshtml přidejte následující zvýrazněný kód:Add the following highlighted code to the Index.cshtml file:
@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1 class="display-4">CORS Test</h1>
</div>

<div>
    <input type="button" value="Test" 
           onclick="requestVal('https://<web app>.azurewebsites.net/api/values')" />
    <span id='result'></span>
</div>

<script>
    function requestVal(uri) {
        const resultSpan = document.getElementById('result');

        fetch(uri)
            .then(response => response.json())
            .then(data => resultSpan.innerText = data)
            .catch(error => resultSpan.innerText = 'See F12 Console for error');
    }
</script>
  1. V předchozím kódu nahraďte url: 'https://<web app>.azurewebsites.net/api/values/1', adresou URL nasazené aplikace.In the preceding code, replace url: 'https://<web app>.azurewebsites.net/api/values/1', with the URL to the deployed app.

  2. Nasaďte projekt API.Deploy the API project. Nasaďte například do Azure.For example, deploy to Azure.

  3. Spusťte aplikaci Razor Pages nebo MVC z plochy a klikněte na tlačítko test .Run the Razor Pages or MVC app from the desktop and click on the Test button. Pomocí nástrojů F12 zkontrolujte chybové zprávy.Use the F12 tools to review error messages.

  4. Odeberte původ localhost z WithOrigins a aplikaci nasaďte.Remove the localhost origin from WithOrigins and deploy the app. Případně spusťte klientskou aplikaci s jiným portem.Alternatively, run the client app with a different port. Například spusťte ze sady Visual Studio.For example, run from Visual Studio.

  5. Otestujte pomocí klientské aplikace.Test with the client app. Chyby CORS vracejí chybu, ale chybová zpráva není k dispozici pro JavaScript.CORS failures return an error, but the error message isn't available to JavaScript. K zobrazení chyby použijte kartu konzola v nástrojích F12.Use the console tab in the F12 tools to see the error. V závislosti na prohlížeči se zobrazí chyba (v konzole nástrojů F12), která je podobná následující:Depending on the browser, you get an error (in the F12 tools console) similar to the following:

    • Používání Microsoft Edge:Using Microsoft Edge:

      SEC7120: [CORS] původ https://localhost:44375 nebyl nalezen https://localhost:44375 v hlavičce odpovědi Access-Control-Allow-Origin pro prostředek pro více zdrojů, v https://webapi.azurewebsites.net/api/values/1SEC7120: [CORS] The origin https://localhost:44375 did not find https://localhost:44375 in the Access-Control-Allow-Origin response header for cross-origin resource at https://webapi.azurewebsites.net/api/values/1

    • Použití Chrome:Using Chrome:

      Zásada CORS zablokovala přístup k XMLHttpRequest v https://webapi.azurewebsites.net/api/values/1 od původu https://localhost:44375: v požadovaném prostředku není k dispozici hlavička Access-Control-Allow-Origin.Access to XMLHttpRequest at https://webapi.azurewebsites.net/api/values/1 from origin https://localhost:44375 has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Koncové body s podporou CORS se dají testovat pomocí nástroje, jako je Fiddler nebo post.CORS-enabled endpoints can be tested with a tool, such as Fiddler or Postman. Při použití nástroje se musí původ požadavku určeného hlavičkou Origin lišit od hostitele, který požadavek přijal.When using a tool, the origin of the request specified by the Origin header must differ from the host receiving the request. Pokud požadavek není mezi zdroji založen na hodnotě hlavičky Origin:If the request isn't cross-origin based on the value of the Origin header:

  • Pro zpracování žádosti není nutné middleware CORS.There's no need for CORS Middleware to process the request.
  • V odpovědi nejsou vraceny hlavičky CORS.CORS headers aren't returned in the response.

CORS ve službě IISCORS in IIS

Při nasazování do služby IIS musí CORS běžet před ověřováním systému Windows, pokud server není nakonfigurovaný tak, aby povoloval anonymní přístup.When deploying to IIS, CORS has to run before Windows Authentication if the server isn't configured to allow anonymous access. Pro podporu tohoto scénáře je nutné nainstalovat a nakonfigurovat modul IIS CORS pro aplikaci.To support this scenario, the IIS CORS module needs to be installed and configured for the app.

Další zdrojeAdditional resources