Ön kontrol isteğine yanıt erişim kontrol kontrolünden geçmiyor


458

Amazon Web Services bir REST API çağırmak için ngResource kullanarak bu hatayı alıyorum:

XMLHttpRequest http://server.apiurl.com:8000/s/login?login=facebook dosyasını yükleyemiyor . Ön kontrol isteğine yanıt erişim kontrol denetimini geçmiyor: İstenen kaynakta 'Erişim-Denetim-İzin Verme Başlığı' başlığı yok. ' Http: // localhost ' kaynağının bu nedenle erişime izin verilmiyor. Hatası 405

Hizmet:

socialMarkt.factory('loginService', ['$resource', function($resource){    
    var apiAddress = "http://server.apiurl.com:8000/s/login/";
    return $resource(apiAddress, { login:"facebook", access_token: "@access_token" ,facebook_id: "@facebook_id" }, {
                getUser: {method:'POST'}
            });
}]);

Denetleyici:

[...]
loginService.getUser(JSON.stringify(fbObj)),
                function(data){
                    console.log(data);
                },
                function(result) {
                    console.error('Error', result.status);
                }
[...]

Chrome kullanıyorum ve bu sorunu çözmek için başka ne yapacağımı bilmiyorum. Sunucuyu bile başlıkları kabul edecek şekilde yapılandırdım localhost.


karıştı: "sunucu yapılandırmak" mı yoksa bu "amazon web hizmetinde bir dinlenme api" mi?
dandavis

3
Sunucu tarafında CORS'yi etkinleştirmek için yeterince şey yapmadınız. Yanıt başlıklarının örneğini
gönderin

4
Her iki durumda da oylarınız yanlış. Dosyalarını yerel makinesinde barındırıyor. Arka uçta ne tür bir sırrı olduğu önemli değil. Açısal bu uçuş öncesi izin vermez.
E. Maggini

3
Yorumlar için teşekkürler, tarayıcıyı güvenli hale getirmek için ayarladığımda çalıştı
Andre Mendes

1
@Andre Ancak güvenliği kapatmak, güvenlikten ödün verdiğiniz çirkin bir çözümdür, sorununuzu çözmez ...
shivi

Yanıtlar:


241

CORS sorunları ile karşılaşıyorsunuz.

Bunu düzeltmenin / geçici çözümün birkaç yolu vardır.

  1. CORS'i kapatın. Örneğin: kromdaki korsalar nasıl kapatılır
  2. Tarayıcınız için bir eklenti kullanın
  3. Nginx gibi bir proxy kullanın. kurulum örneği
  4. Sunucunuz için gerekli kurulumu yapın. Bu, EC2 örneğinize yüklediğiniz web sunucusunun bir faktörüdür (bunun "Amazon web hizmeti" ile kastettiğini varsayarsak). Özel sunucunuz için CORS'yi etkinleştir web sitesine bakabilirsiniz .

Daha ayrıntılı olarak, localhost'tan api.serverurl.com adresine erişmeye çalışıyorsunuz. Alanlar arası isteğin tam tanımı budur.

Sadece işinizi halletmek için kapatarak (Tamam, diğer siteleri ziyaret ederseniz ve sadece kutuyu yoldan çıkarırsanız sizin için kötü güvenlik koyun), tarayıcınızın tüm isteklerin yerel ana bilgisayardan geldiğini düşünmesini sağlayan bir proxy kullanabilirsiniz. gerçekten sonra uzak sunucuyu çağıran yerel sunucunuz var.

böylece api.serverurl.com localhost olabilir: 8000 / api ve yerel nginx veya diğer proxy'niz doğru hedefe gönderilecektir.


Şimdi popüler talep, % 100 daha fazla CORS bilgi .... aynı harika bir tadı!


Ve downvoter'lar için ... CORS'leri atlamak, sadece ön ucu öğrenenler için gösterilen şeydir. https://codecraft.tv/courses/angular/http/http-with-promises/


776
CORS'u doğru bir şekilde uygulamaktan bariz olanı bıraktı
charlietfl

40
Oy vermek kolaydır. Daha az kolay risk almak arkadaşım. Ve tüm bunlar tam olarak geliştirici bir ortamda çalışıyor.
E. Maggini

3
Aslında işe yaradı. Web güvenliğini devre dışı bırakmak için bayrağı ekledim. Gelişim için iyidir.
Andre Mendes

15
@charlietfl Nasıl?
GreenAsJade

3
Günümü kurtardığın için teşekkürler. Yalnızca ilk seçenek kullanıldı: C: ​​\ Program Dosyaları (x86) \ Google \ Chrome \ Application> chrome.exe --user-data-dir = "C: \ Chrome dev session" --disable-web-security. İtibaren: stackoverflow.com/questions/3102819/…
Harsimer

169

Benim "API Server" bir PHP uygulaması bu yüzden bu sorunu çözmek için çalışmak için aşağıdaki çözümü buldum:

Satırları index.php dosyasına yerleştirin

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');

3
Kabul ediyorum, bu kabul edilen cevaptan daha iyidir, ancak bu satırları kopyalarken dikkatli olun, yöntemleri ve kökeni değiştirdiğinizden emin olun.
Amir Savand

11
Açısal 6 projesine nerede yerleştirilir?
whatthefish

@CodyBugstein ve whatthefish herhangi bir çıktı önce koymak
Garet Claborn

Yalnızca bazı sunucular için gerekli bir başlık eklediğimde istemci uygulamam durdu. İstek herhangi bir özel üstbilgi içeriyorsa, bunların içinde listelenmesi gerekir Access-Control-Allow-Headers.
z0r

47

AspNetCore web api'de, "Microsoft.AspNetCore.Cors" (sürüm 1.1.1) ve Startup.cs dosyasında aşağıdaki değişiklikler eklenerek bu sorun giderildi.

public void ConfigureServices(IServiceCollection services)
{ 
    services.AddCors(options =>
    {
          options.AddPolicy("AllowAllHeaders",
                builder =>
            {
                    builder.AllowAnyOrigin()
                           .AllowAnyHeader()
                           .AllowAnyMethod();
                });
    });
    .
    .
    .
}

ve

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{


    // Shows UseCors with named policy.
    app.UseCors("AllowAllHeaders");
    .
    .
    .
}

ve [EnableCors("AllowAllHeaders")]denetleyiciyi takmak.


18
Siteler arası komut dosyası oluşturma güvenlik açıklarını oluşturmak istiyorsanız bu iyi bir yanıttır! Lütfen bunu asla yapma! Güvenlik sorunlarından kaçınmak için alan adlarınızı erişebileceğiniz şekilde belirtin. CORS bir sebepten dolayı orada.
paqogomez

2
@Paqogomez'i daha netleştirmek için ConfigureServices yönteminizde: services.AddCors (options => {options.AddPolicy ("AllowSpecificOrigin", builder => {builder.WithOrigins (" localhost" ) .AllowAnyOrigin () .AllowAnyHeader (). AllowAnyMethod ();});}); ve Configure yönteminizde: app.UseCors ("AllowSpecificOrigin");
Francisco Tena

28

CORS söz konusu olduğunda bazı uyarılar var. Birincisi, joker karakterlere izin vermiyor *ama beni bu konuda tutmuyor Bir yerde okudum ve makaleyi şimdi bulamıyorum.

Farklı bir alandan istekte bulunuyorsanız, başlangıç ​​noktasına izin ver başlıklarını eklemeniz gerekir.

 Access-Control-Allow-Origin: www.other.com 

Eğer POST / PUT / PATCH gibi sunucu kaynaklarını etkiler ve mim tipi aşağıdakilerden farklı olması durumunda isteklerini yapıyorsanız application/x-www-form-urlencoded, multipart/form-dataya da text/plaintarayıcı otomatik olarak buna izin olsaydı bir uçuş öncesi SEÇENEKLERİ sunucu ile kontrol etmek isteyebilir yapacak .

Bu nedenle, API / sunucunuzun bu SEÇENEKLER isteklerini buna göre ele alması, uygun yanıt vermeniz access control headersve http yanıt durum kodunun olması gerekir 200.

Başlıklar böyle bir şey olmalı, ihtiyaçlarınıza göre ayarlanmalıdır:

   Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
   Access-Control-Allow-Headers: Content-Type
   Access-Control-Max-Age: 86400

Maksimum yaş üstbilgisi önemlidir, benim durumumda, onsuz işe yaramaz, sanırım tarayıcının "erişim hakları" nın ne kadar geçerli olduğuna dair bilgiye ihtiyacı var.

Ayrıca, örneğin farklı bir alan adından mime POSTile bir istekte bulunuyorsanız application/json, daha önce belirtilen izin verilen kaynak başlığını da eklemeniz gerekir, bu nedenle şöyle görünür:

   Access-Control-Allow-Origin: www.other.com 
   Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
   Access-Control-Allow-Headers: Content-Type
   Access-Control-Max-Age: 86400

Uçuş öncesi başarılı olduğunda ve gerekli tüm bilgileri aldığında gerçek talebiniz yapılır.

Genel olarak, Access-Controlilk ya da uçuş öncesi talepte hangi başlıklar istenirse, çalışabilmesi için cevapta verilmelidir.

Bu bağlantıdaki MDN belgelerinde iyi bir örnek var ve ayrıca bu SO postasını da kontrol etmelisiniz


1
Mozilla makalesi, cors orijini için joker karakteri nasıl kullanamayacağınız hakkında konuşuyor: Link Görünüşe göre bu sadece kimlik bilgilerini kullanırken geçerlidir (doğru anlıyorsam)
Helzgate

Joker karakter kullanıyorum ve isteği yetkilendirmek için bir taşıyıcı belirteci gönderiyorum ve yukarıda sağladığım bağlantının kimlik bilgileriyle ilgili neye atıfta bulunduğundan emin değil. Benim sorunum .Net Core'da CORS politikamı oluştururken eklemedim .AllowCredentials(). Ekledikten sonra .AllowCredentials()her şey çalıştı.
Helzgate

15

JavaScript XMLHttpRequest ve Fetch aynı köken politikasını izler. Bu nedenle, XMLHttpRequest veya Fetch kullanan bir web uygulaması yalnızca kendi etki alanına HTTP isteklerinde bulunabilir.

Kaynak: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Sen göndermek zorunda *: Erişim-Control-Allow-Origin sunucu tarafında HTTP başlığı.

HTTP sunucunuz olarak Apache kullanıyorsanız, Apache yapılandırma dosyanıza şu şekilde ekleyebilirsiniz:

<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
</IfModule>

Mod_headers Apache'de varsayılan olarak etkindir, ancak aşağıdakileri çalıştırarak etkinleştirilmesini isteyebilirsiniz:

 a2enmod headers

Apache yapılandırma dosyamı nerede bulabilirim?
Shubham Arya

Linux Debian'da @ShubhamArya varsayılan konum:/etc/apache2/apache2.conf
Tadej

pencerelerde nerede bulabilirim?
Shubham Arya

10

Bir krom uzantısı yazıyorsanız

manifest.jsonAlan adlarınız için izinleri eklemeniz gerekir .

"permissions": [
   "http://example.com/*",
   "https://example.com/*"
]

1
Ayrıca www ön
ekiniz

8

IIS sunucusunu tesadüfen kullanıyorsanız. HTTP istek başlıkları seçeneğinde aşağıdaki başlıkları ayarlayabilirsiniz.

Access-Control-Allow-Origin:*
Access-Control-Allow-Methods: 'HEAD, GET, POST, PUT, PATCH, DELETE'
Access-Control-Allow-Headers: 'Origin, Content-Type, X-Auth-Token';

bu ile tüm yazı, olsun vb, iyi çalışacaktır.



5

PHP'de üstbilgileri ekleyebilirsiniz:

<?php
header ("Access-Control-Allow-Origin: *");
header ("Access-Control-Expose-Headers: Content-Length, X-JSON");
header ("Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS");
header ("Access-Control-Allow-Headers: *");
...

teşekkürler, benim için çalıştı! testler ve üretim ortamında. Hatta https: //
Jose Seie

1
@atiruz Çözüm için teşekkürler. Çizgiyi Eklediğimde Çalışıyorheader ("Access-Control-Expose-Headers: Content-Length, X-JSON");
Silambarasan RD

5

Bir Düğüm JS uygulamasında çapraz kökenli istek sorunlarını gidermek için:

npm i cors

Ve aşağıdaki satırları app.js

let cors = require('cors')
app.use(cors())

3
bu sadece ekspres js uygulamalarında çalışır, tüm düğüm uygulamalarında değil
DrCord

3

Apache VirtualHost yapılandırma dosyamda aşağıdaki satırları ekledim:

Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"

RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]

3

API Gateway ile Lambda Integrated Proxy kullananlar için . Lambda işlevinizi, isteklerinizi doğrudan gönderiyormuşsunuz gibi yapılandırmanız gerekir; bu, işlevin yanıt başlıklarını düzgün ayarlaması gerektiği anlamına gelir. (Özel lambda işlevleri kullanıyorsanız, bu API Ağ Geçidi tarafından ele alınacaktır.)

//In your lambda's index.handler():
exports.handler = (event, context, callback) => {
     //on success:
     callback(null, {
           statusCode: 200,
           headers: {
                "Access-Control-Allow-Origin" : "*"
           }
     }
}

1
Ben de chime ve AWS belgeleri sanmıyorum bir büyük gotcha bahsetmek istiyorum. Lambda işlevinizi proxy yapmak için API ağ geçidi kullandığınızı ve bu lambda işlevinde bazı API kullandığınızı varsayalım. Bu API 200 olmayan bir başarı başarı kodu döndürürse ve 200 olmayan başarı kodunu API ağ geçidindeki yöntem yanıtına eklemediyseniz, bir hata alırsınız ve başarılı yanıtınızı görmezsiniz . Bunun örnekleri: Sendgrid ve Twilio'nun 200 dışında başarı kodu vardır.
Stephen Tetreault

3

Sanırım CORS'u Chrome'dan devre dışı bırakmak iyi bir yol değil , çünkü eğer iyonik olarak kullanıyorsanız, kesinlikle Mobile Build'da Sorun Tekrar ortaya çıkacaktır.

Arka ucunuzda düzeltmek daha iyi.

Her şeyden önce başlıkta,

  • başlık ('Access-Control-Allow-Origin: *');
  • header ('Header set Access-Control-Allow-Headers: "Origin, X-Requested With With, İçerik Türü, Kabul Et"');

API, GET ve POST olarak davranıyorsa, başlığınızda da ayarlayın.

if ($ _SERVER ['REQUEST_METHOD'] == 'SEÇENEKLER') {if (isset ($ _ SERVER ['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) başlık ("Erişim-Kontrol-İzin Ver-Yöntemler: GET, POST, OPTIONS");
if (isset ($ _ SERVER ['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) başlık ("Access-Control-Allow-Headers:
{$ _SERVER ['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); çıkış (0); }


3

Bu hatanın çok yaygın bir nedeni, ana makine API'sının isteği bir http yöntemiyle (ör. PUT) eşlemiş olması ve API istemcisinin farklı bir http yöntemi (ör. POST veya GET) kullanarak API'yı çağırması olabilir.


PUT
Sunucumda

3

Ekibimiz bunu bazen Vue, axios ve bir C # WebApi kullanarak görür. Vurmaya çalıştığınız uç noktaya bir rota özelliği eklemek bizim için düzeltiyor.

[Route("ControllerName/Endpoint")]
[HttpOptions, HttpPost]
public IHttpActionResult Endpoint() { }

Neden olduğundan gerçekten emin değiliz. Lol. Biri bana haber verirse!
w00ngy

1

DNS sunucusu 8.8.8.8 (google) olarak ayarlandığında bu sorunla karşılaştım. Aslında, sorun yönlendiricideydi, uygulamam yerel olarak değil, google üzerinden sunucuya bağlanmaya çalıştı (özel durumum için). 8.8.8.8'i kaldırdım ve bu sorunu çözdü. Bu sorunların CORS ayarları tarafından çözüldüğünü biliyorum, ama belki birilerinin benimle aynı sorunu yaşayacağı


1

Yüklemeler için AWS sdk kullanıyorum, çevrimiçi arama yapmak için biraz zaman geçirdikten sonra bu iş parçacığını tökezledi. @lsimoneau 45581857 sayesinde aynı şeylerin olduğu ortaya çıkıyor. Bölge seçeneğimi takarak URL'mi bölgemdeki bölgeye işaret ettim ve işe yaradı.

 const s3 = new AWS.S3({
 accessKeyId: config.awsAccessKeyID,
 secretAccessKey: config.awsSecretAccessKey,
 region: 'eu-west-2'  // add region here });

0

GeoServer'ın bağımsız dağıtımları Jetty uygulama sunucusunu içerir. Kendi alan adınız dışındaki JavaScript uygulamalarının GeoServer kullanmasına izin vermek için Kaynaklar Arası Kaynak Paylaşımı'nı (CORS) etkinleştirin.

Aşağıdakileri <filter>ve <filter-mapping>webapps / geoserver / WEB-INF / web.xml'den gelenleri kaldırın:

<web-app>
  <filter>
      <filter-name>cross-origin</filter-name>
      <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>cross-origin</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

Bu yanıt başlığına antyhing eklemedi, bu yüzden işe yaramadı
JollyRoger

1
GeoServer kullanmıyor, ancak bu klip aramayı alan uygulamada kullanmam gereken ayarları bilmeme yardımcı oldu.
Matt Felzani

0

Bu sorunu, hiçbir şeyden endişe etmeden, sadece birkaç adımla kolayca çözmek mümkündür. Nazikçe, çözmek için adımları izleyin.

  1. open ( https://www.npmjs.com/package/cors#enabling-cors-pre-flight )
  2. kuruluma gidin ve düğüm terminali üzerinden kurmak için npm install cors komutunu kopyalayın
  3. Kaydırma yaparak Basit Kullanım (Tüm CORS İsteklerini Etkinleştir) seçeneğine gidin. daha sonra tüm bildirimi kopyalayın ve ur projenize yapıştırın ve çalıştırın ... Bu kesinlikle işe yarayacaktır .. yorum kodunu kopyalayın ve ur app.js veya başka bir yere yapıştırın proje ve bir deneyin .. bu çalışacaktır. bu her çapraz kaynak paylaşımı kilidini olacak .. böylece kullanım için hizmet arasında geçiş yapabilirsiniz

1
var express = requir ('express') var cors = requir ('cors') var app = express () app.use (cors ()) app.get ('/ ürünler /: id', işlev (req, res, sonraki) {res.json ({msg: 'Bu, tüm kökenler için CORS etkin!'})}) app.listen (80, function () {console.log ('80 numaralı bağlantı noktasında CORS etkin web sunucusu dinleme' )})
Rahul sah

-1

Kaçırması çok kolay bir şey ...

Solution explorer'da api-project'e sağ tıklayın. Özellikler penceresinde 'Anonim Kimlik Doğrulaması'nı Etkin olarak ayarlayın !!!


-8

Krom güvenliğini devre dışı bırakın. Bir krom kısayolu oluşturun sağ tıklama -> özellikler -> hedef, yapıştırın "C: \ Program Files (x86) \ Google \ Chrome \ Application \ chrome.exe" --disable-web-security --user -veri-dir = "c: / chromedev"

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.