Ön kontrol yanıtında istek üstbilgisi alanına Erişim-Denetim-İzin Ver-Başlıkları izin verilmiyor


234

Ben CORS sorunları defalarca karşılaştım ve genellikle düzeltebilirsiniz ama ben bunu gerçekten bir yığın yığını paradigmasından görerek anlamak istiyorum.

Ben sadece bu şeyleri yakalamak için ekspres sunucuma ara katman yazılımı eklemeden önce, ama benim istekleri dışarı hata ön kanca bir tür gibi görünüyor.

Ön kontrol yanıtında Access-Control-Allow-Headers tarafından istek başlığı alanına Access-Control-Allow-Headers'a izin verilmiyor

Bunu yapabileceğimi varsaydım:

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

ya da eşdeğeri ancak bu sorunu çözmüyor gibi görünüyor. Tabii ki denedim

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

Hala şans yok.

Yanıtlar:


245

Özel istek başlıklarıyla oynamaya başladığınızda CORS ön kontrolüne sahip olursunuz. Bu, HTTP OPTIONSfiilini kullanan ve biri Access-Control-Request-Headersistemcinin isteğe eklemek istediği başlıkları listeleyen birkaç başlık içeren bir istektir.

Bu işi yapmak için ilgili CORS ön kontrolüne uygun CORS başlıklarıyla yanıt vermeniz gerekir. Bunlardan biri gerçekten Access-Control-Allow-Headers. Bu üstbilgi, Access-Control-Request-Headersüstbilginin (veya daha fazlasının) içerdiği değerleri içermelidir .

https://fetch.spec.whatwg.org/#http-cors-protocol bu kurulumu daha ayrıntılı olarak açıklıyor.


41
Chrome kullanıyorsanız ve hangi başlıkların istendiğinden emin değilseniz, Geliştirici Konsolu'nu kullanın, Ağ aranacak aramayı seçin ve hangi başlıkların istendiğini görebilirsinizAccess-Control-Request-Headers
Lionel Morrison

5
Geliştirici Konsolu seçeneği iyi bir seçenek. İhtiyacınız olanı sunucudaki istek nesnesine erişip üstbilgilerin değerlerini, özellikle de "Erişim-Denetim-İstek-Üstbilgileri" için başlık değerini dökerek de bulabilirsiniz. Ardından, kopyalayıp yanıtınıza yapıştırın. SetHeader ("Access-Control-Allow-Headers", "{buraya yapıştırın}")
Yazılım Peygamberleri

7
örnek lütfen!
17'de

5
@Demodave benim için bunun bir örneği olduheader("Access-Control-Allow-Headers: Content-Type")
Joshua Duxbury

1
@LionelMorrison, başlıkları eşleştirmek için krom geliştirme araçlarının kullanımı. iyi açıkladı !!!
Savina Chandla

119

Çalışması için eklemeniz gereken budur.

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");

Tarayıcı, sunucuda barındırılan hizmete farklı bir etki alanındaki tarayıcıdan erişilmesine izin verilip verilmediğini kontrol etmek için bir ön kontrol isteği (OPTIONS yöntemiyle) gönderir. Yukarıdaki başlıklara enjekte ederseniz ön kontrol talebine yanıt olarak, tarayıcı daha fazla çağrı yapmanın uygun olduğunu anlar ve gerçek GET / POST çağrım için geçerli bir yanıt alırım. * yerine Access-Control-Allow-Origin "," localhost, xvz.com "kullanarak erişim verilen etki alanını kısıtlayabilirsiniz. (* tüm etki alanlarına erişim izni verecektir)


7
*İçin ...-Originve trueiçin birleştiremezsiniz ...-Credentials. Kimlik bilgisi alınmayan istekler için başarısız olmaz, ancak kimlik bilgisi talepleri için de çalışmaz. Cevabımda gönderdiğim bağlantıya bakın.
Anne

Teşekkürler Manish Arora, çözümümü API'mde kullandım ve işe yaradı. HttpContext.Response.Headers.Add ("Erişim-Denetim-İzin Ver Yöntemleri", "GET, HEAD, OPTIONS, POST, PUT"); HttpContext.Response.Headers.Add ("Erişim-Denetim-İzin Ver-Başlıkları", "Erişim-Denetim-İzin Ver-Başlıkları, Köken, Kabul Et, X-Talep Edilen-İle, İçerik Türü, Erişim-Denetim-İstek-Yöntemi, Erişim ")-İstek-Başlıkları -Kontrol; HttpContext.Response.Headers.Add ("Access-Control-Allow-Origin", " localhost: 4200" );
Ramakrishnankt

1
Bu sunucu tarafı "ön kontrol" nedeniyle tüm bu yanıt başlığı munging gerekli diyor? Neden? Özellikle mükemmel standart başlıklar için? HTTP'yi bir süre kullandıktan sonra, çok fazla kaynak plakasına ihtiyaç duyulduğu benim için bir haber.
Samantha Atkins

@manish Access-Control-Allow-Headers için çalışmayan farklı bir değer grubum vardı. Değer kümeniz yaptı. Zamandan ve hayal kırıklığından tasarruf ettiğiniz için teşekkür ederiz.
azakgaim

Bazı başlıkları joker olarak işaretlemenin bir yolu var mı? Tüm başlıkları joker karakterle yazmak kötü bir fikir mi? Gibi response.setHeader("Access-Control-Allow-Headers", "*")? Bunu yapmanın güvenlik anlamı nedir?
Vadorequest

78

Bu problem çözüldü

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

Projemde özellikle (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();
});

Güncelleme:

Her defasında hata: Access-Control-Allow-Headers is not allowed by itself in preflight responsehata, Chrome geliştirici aracında neyin yanlış olduğunu görebilirsiniz :
resim açıklamasını buraya girin

Yukarıdaki hata eksik Content-Typedize ekleyin böylece Content-TypeiçinAccess-Control-Allow-Headers


1
Bu herkes için işe yaramaz. Erişim-Denetim-İstek-Başlıkları değeri ortama bağlı olarak değişebilir. Sunucudaki istek nesnesine erişin ve "Erişim-Denetim-İstek-Başlıkları" üstbilgisi değerlerini dökün. Ardından, kopyalama / senin response.setHeader yapıştırabilirsiniz ( "Erişim Kontrol-Başlıkları izin ver", "{buraya yapıştırın}")
Yazılım Peygamberler

1
Ayrıca Yetkilendirmeyi Britsh yoluna değil amerikan yoluna yazdığınızdan emin olun. Hayatımın yarım saatini geri almayacağım. Teşekkürler ABD! [iç çekiş]
jeoidesik

14

Kabul edilen cevap iyi, ama bunu anlamakta zorlandım. İşte size açıklığa kavuşturmak için basit bir örnek.

Ajax isteğimde standart bir Yetkilendirme başlığım vardı.

$$(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);
}

Bu kod sorudaki hatayı üretir. Düğümler sunucumda yapmam gereken izin verilen başlıklara Yetkilendirme eklemekti:

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

6

Diğer cevaplara eklemek için. Aynı sorunu vardı ve bu benim ekspres sunucum REST çağrıları izin için kullanılan kod:

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

Bu kod temel olarak tüm istekleri durdurur ve CORS başlıklarını ekler, sonra normal rotalarıma devam eder. SEÇENEKLER isteği olduğunda yalnızca CORS başlıklarıyla yanıt verir.

DÜZENLEME: Bu düzeltmeyi aynı makinedeki iki ayrı nodejs express sunucusu için kullanıyordum. Sonunda sorunu basit bir proxy sunucusuyla çözdüm.


Teşekkürler! Basit bir proxy sunucusunu nasıl kullandığınız hakkında ayrıntılı bilgi verebilir misiniz?
austin_ce

5

ASP.NET bağlamında Web.config'inizin şöyle göründüğünden emin olun:

  <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-HeadersAnahtar için Yetkilendirme değerine dikkat edin . Yetkilendirme değerini kaçırıyordum, bu yapılandırma sorunumu çözdü.


5

Çok iyi bir silex projesinde kullandım

$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");
    });

2
Bu kod soruyu cevaplayabilirken, sorunun nasıl ve / veya neden çözüldüğüne ilişkin ek bağlam sağlamak yanıtlayıcının uzun vadeli değerini artıracaktır.
Badacadabra

4

Chrome'da:

Ön kontrol yanıtında X-Requested-With üstbilgi alanına Access-Control-Allow-Headers tarafından izin verilmez.

Benim için bu hata, bu çağrının URL'sindeki bir boşluk tarafından tetiklendi .

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

3

Sadece eklemek için bu başlıkları Webpack yapılandırma dosyasına de koyabilirsiniz. Webpack dev sunucusunu çalıştırdığım için onlara ihtiyacım vardı.

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

OP'nin Django, React ve django-cors-headers lib kullanarak belirttiği hatayı aldım. Bu yığınla düzeltmek için aşağıdakileri yapın:

Settings.py'de resmi belgelere göre aşağıdakileri ekleyin .

from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = default_headers + (
'YOUR_HEADER_NAME',
)

2

Bu sorun, istek için özel üstbilgi yaptığımızda oluşur. HTTP OPTIONS , birkaç üstbilgi ve içerir.

Bu istek için gerekli üstbilgi Access-Control-Request-Headers, yanıt üstbilgisinin bir parçası olmalı ve tüm kaynaklardan gelen isteğe izin vermelidir. Bazen Content-Typeyanıt başlığında da gerekir . Dolayısıyla yanıt başlığınız şöyle olmalıdır -

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");

1

Post API çağrısında istek gövdesinde veri gönderiyoruz. Dolayısıyla, bir API çağrısına ekstra başlık ekleyerek veri gönderirsek. Sonra ilk SEÇENEKLER API çağrısı gerçekleşecek ve sonra çağrı sonrası gerçekleşecek. Bu nedenle, önce OPTION API çağrısını yönetmeniz gerekir.

Bir filtre yazarak ve içinde seçenek çağrısı API çağrısı olup olmadığını kontrol etmeniz ve 200 OK durumu döndürmeniz gereken sorunu çözebilirsiniz. Örnek kod aşağıdadır:

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

İstek üstbilgilerine özel bir üstbilgi eklemeye çalışıyorsanız, sunucuya belirli bir üstbilginin gerçekleşmesine izin verildiğini bildirmeniz gerekir. Yapılacak yer istekleri filtreleyen sınıftadır. Aşağıda gösterilen örnekte, özel başlık adı "tür" dür:

public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin",  request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,PATCH,OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Authorization, type ");
        response.setHeader("Access-Control-Expose-Headers","Authorization");
    }
}

1

Neredeyse bir gün geçirdikten sonra, aşağıdaki iki kodu eklemenin sorunumu çözdüğünü öğrendim.

Bunu Global.asax'a ekleyin

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

ve web yapılandırmasına aşağıdakileri ekleyin

<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

Açısal 6'da da aynı sorunla karşılaştım. Aşağıdaki kodu kullanarak sorunu çözdüm. Kodu component.ts dosyasına ekleyin.

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

Karşılaştığım aynı sorun.

Basit bir değişiklik yaptım.

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

0

API'da 'Yetkilendirmeye' izin verilmediğine dair mesaj açık. Set
Access-Control-Allow-Başlıkları: "Content-Type, Yetki"


0
const express = require('express')
const cors = require('cors')
const app = express()

app.get('/with-cors', cors(), (req, res, next) => {
  res.json({ msg: 'WHOAH with CORS it works! 🔝 🎉' })
})

Get işlevinde kor eklemek Benim için işe yarayan şey

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.