Origin wird von Access-Control-Allow-Origin nicht zugelassen


337

Ich mache eine Verbindung Ajax.requestzu einem Remote-PHP-Server in einer Sencha Touch 2-Anwendung (in PhoneGap verpackt ).

Die Antwort vom Server lautet wie folgt:

XMLHttpRequest kann http://nqatalog.negroesquisso.pt/login.php nicht laden . Origin http://localhost:8888wird von Access-Control-Allow-Origin nicht zugelassen.

Wie kann ich dieses Problem beheben?


19
Während Sie jQuery verwenden, dataType: 'jsonp',reicht die Einstellung aus
am

11
Übrigens ist das nicht die Antwort vom Server. Um genau zu sein, wird dieser Fehler auf der Client-Seite ausgegeben.
Matto

2
Der Jsonp-Trick funktioniert wahrscheinlich nicht mehr, fyi: stackoverflow.com/questions/12216208/…
zog

7
Hinweis: Da ich gerade einen halben Tag damit verbracht habe, diesen Fehler zu verfolgen - Wenn das serverseitige Skript mit einem internen Serverfehler fehlschlägt, interpretiert der Browser ihn möglicherweise so, als wäre die Anforderung aufgrund Access-Control-Allow-Origindes Fehlers nicht zulässig, und meldet dies als Fehler.
Troelskn

1
@troelskn Du hast gerade mein Leben gerettet. Ich habe seit 3 ​​Tagen nach einem CORS-Fehler gesucht und es war einfach ein kleines Spring-Konfigurationsproblem, das einen 500 verursachte, das ich in 5 Minuten gelöst habe, nachdem ich Ihren Kommentar gelesen und tatsächlich danach gesucht hatte. Vielen Dank!
Alexis Dufrenoy

Antworten:


378

Ich habe vor einiger Zeit einen Artikel zu diesem Thema geschrieben, Cross Domain AJAX .

Wenn Sie die Kontrolle über den antwortenden Server haben, können Sie dies am einfachsten tun, indem Sie einen Antwortheader hinzufügen für:

Access-Control-Allow-Origin: *

Dies ermöglicht domänenübergreifendes Ajax . In PHP möchten Sie die Antwort folgendermaßen ändern:

<?php header('Access-Control-Allow-Origin: *'); ?>

Sie können die Header set Access-Control-Allow-Origin *Einstellung einfach in die Apache- Konfiguration oder die htaccess-Datei einfügen.

Es sollte beachtet werden, dass dies den CORS-Schutz effektiv deaktiviert, wodurch Ihre Benutzer sehr wahrscheinlich Angriffen ausgesetzt sind . Wenn Sie nicht wissen, dass Sie speziell einen Platzhalter verwenden müssen, sollten Sie ihn nicht verwenden. Stattdessen sollten Sie Ihre spezifische Domain auf die Whitelist setzen:

<?php header('Access-Control-Allow-Origin: http://example.com') ?>

4
Ich werde meinen Server-Provider kontaktieren. Vielen Dank
Ricardo

8
Gibt es Sicherheitsbedenken? In dieser Antwort heißt es beispielsweise: "JavaScript ist aus Sicherheitsgründen durch die" gleiche Ursprungsrichtlinie "eingeschränkt. Beispielsweise kann ein böswilliges Skript keinen Remote-Server kontaktieren und vertrauliche Daten von Ihrer Site senden."
JohnK

4
Genial, ich habe dies einfach in meine node.js-Serverdatei eingefügt: response.writeHead (200, {'Content-Type': contentType, 'Access-Control-Allow-Origin': '*'}); Und es hat funktioniert. Vielen Dank!
Vbullinger

25
JohnK, ja, mit dem Platzhalter kann jede Domain Anfragen an Ihren Host senden. Ich empfehle, das Sternchen durch eine bestimmte Domäne zu ersetzen, für die Sie Skripts ausführen.
Nick

7
Es ist interessant, dass Sie denken, dass der Platzhalter nicht einmal @jfrej vorgeschlagen werden sollte. Es hängt alles von Ihrem Ziel ab. Der Grund, warum wir den Platzhalter verwendet haben (und diese Antwort gepostet haben), war beispielsweise, dass wir ein eingebettetes Widget für jede Site erstellt haben.
Matt Mombrea

63

Wenn Sie keine Kontrolle über den Server haben, können Sie dieses Argument einfach zu Ihrem Chrome-Starter hinzufügen : --disable-web-security.

Beachten Sie, dass ich dies nicht für normales "Surfen im Internet" verwenden würde. Weitere Informationen finden Sie in diesem Beitrag: Deaktivieren Sie dieselbe Ursprungsrichtlinie in Chrome .

Wenn Sie Phonegap verwenden, um die Anwendung tatsächlich zu erstellen und auf das Gerät zu laden, ist dies kein Problem.


Vielen Dank. Aber meine App läuft auf mobilen Geräten. Ich kann keine Argumente an meinen Webview-Wrapper übergeben.
Ricardo

Testen Sie Ihre App nicht zuerst in einem Browser? Wie debuggen Sie?
Travis Webb

Ja, ich debugge in einem Chrome-Browser, aber die App läuft nicht auf Chrome. Es wird auf Phonegap Webview sein, was ich nicht kontrollieren kann.
Ricardo

4
Lesen Sie die Antwort: Sie können dieses Argument einfach zu Ihrem Chrome-Launcher hinzufügen . Es gibt keine Einstellung dafür in Chrome
Travis Webb

2
Natürlich ist es unsicher. Das OP fordert einen Weg, um die Sicherheitsmaßnahmen zu umgehen.
Travis Webb

42

Wenn Sie Apache verwenden, fügen Sie einfach Folgendes hinzu:

<ifModule mod_headers.c>
    Header set Access-Control-Allow-Origin: *
</ifModule>

in Ihrer Konfiguration. Dadurch können alle Antworten von Ihrem Webserver von jeder anderen Website im Internet aus aufgerufen werden. Wenn Sie nur zulassen möchten, dass Dienste auf Ihrem Host von einem bestimmten Server verwendet werden, können Sie die *durch die URL des Ursprungsservers ersetzen :

Header set Access-Control-Allow-Origin: http://my.origin.host

3
Und vergessen Sie nicht, Modul zu laden: a2enmod Header
Walery Strauch

Wie lade ich ein Modul: a2enmod Header?
Ayesha

18

Wenn Sie eine ASP.NET / ASP.NET MVC- Anwendung haben, können Sie diesen Header über die Datei Web.config einfügen:

<system.webServer>
  ...

    <httpProtocol>
        <customHeaders>
            <!-- Enable Cross Domain AJAX calls -->
            <remove name="Access-Control-Allow-Origin" />
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

2
.NET MVC Leute, schau hier! Ich werde tatsächlich eine Lösung eingeben und auf diese Antwort in meinem Blog verweisen, damit die Leute sie leichter finden können. Nichts ist schlimmer als zu versuchen, eine .NET / MVC-Hürde zu überwinden und nur PHP / jQuery-Lösungen zu finden. Danke @ Caio-Proiete
ottoflux

1
Wie kommt es, dass das bei mir nicht funktioniert? Ich verwende Chrome und versuche, von meinem lokalen Host aus auf die Yahoo-Finanzseite zuzugreifen.
Newman

1
Danke, es hat bei mir funktioniert. Ich habe im serverseitigen Code-Projekt (web.config) hinzugefügt.
Ethem

15

Dies war die erste Frage / Antwort, die für mich auftauchte, als ich versuchte, dasselbe Problem mit ASP.NET MVC als Quelle meiner Daten zu lösen . Mir ist klar, dass dies die PHP- Frage nicht löst , aber es ist verwandt genug, um wertvoll zu sein.

Ich verwende ASP.NET MVC. Der Blogbeitrag von Greg Brant hat für mich funktioniert. Letztendlich erstellen Sie ein Attribut, [HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]das Sie zu Controller-Aktionen hinzufügen können.

Zum Beispiel:

public class HttpHeaderAttribute : ActionFilterAttribute
{
    public string Name { get; set; }
    public string Value { get; set; }
    public HttpHeaderAttribute(string name, string value)
    {
        Name = name;
        Value = value;
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.AppendHeader(Name, Value);
        base.OnResultExecuted(filterContext);
    }
}

Und dann mit:

[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]
public ActionResult MyVeryAvailableAction(string id)
{
    return Json( "Some public result" );
}

1
WebApi 2 hat dies jetzt eingebaut. asp.net/web-api/overview/security/…
Matt Frear

10

Da Matt Mombrea für die Serverseite korrekt ist, können Sie auf ein anderes Problem stoßen, nämlich die Ablehnung der Whitelist.

Sie müssen Ihre phonegap.plist konfigurieren. (Ich benutze eine alte Version von Phonegap)

Bei Cordova gibt es möglicherweise einige Änderungen in der Benennung und im Verzeichnis. Die Schritte sollten jedoch größtenteils gleich sein.

Wählen Sie zuerst Unterstützende Dateien> PhoneGap.plist

Geben Sie hier die Bildbeschreibung ein

dann unter "ExternalHosts"

Fügen Sie einen Eintrag mit dem Wert " http://nqatalog.negroesquisso.pt " hinzu. Ich verwende * nur für Debugging-Zwecke.

Geben Sie hier die Bildbeschreibung ein


8

Dies kann für alle nützlich sein, die eine Ausnahme sowohl für "www" - als auch für "nicht www" -Versionen eines Referrers benötigen:

 $referrer = $_SERVER['HTTP_REFERER'];
 $parts = parse_url($referrer);
 $domain = $parts['host'];

 if($domain == 'google.com')
 {
         header('Access-Control-Allow-Origin: http://google.com');
 }
 else if($domain == 'www.google.com')
 {
         header('Access-Control-Allow-Origin: http://www.google.com');
 }

Hat mich in die richtige Richtung gelenkt, um den ACAO-Fehler mit Azure zu beheben. Während ich erlaubte Hostname von googledrive hinzugefügt hatte. Die verwendete URL muss googledrive sein, NICHT googledrive
Kildareflare

7

Ich werde Ihnen eine einfache Lösung für diese geben. In meinem Fall habe ich keinen Zugriff auf einen Server. In diesem Fall können Sie die Sicherheitsrichtlinie in Ihrem Google Chrome- Browser ändern , um Access-Control-Allow-Origin zuzulassen. Das ist sehr einfach:

  1. Erstellen Sie eine Chrome-Browserverknüpfung
  2. Klicken Sie mit der rechten Maustaste auf das Verknüpfungssymbol -> Eigenschaften -> Verknüpfung -> Ziel

Einfach einfügen "C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-security.

Der Standort kann abweichen. Öffnen Sie nun Chrome, indem Sie auf diese Verknüpfung klicken.


7

Ich bin einige Male darauf gestoßen, wenn ich mit verschiedenen APIs gearbeitet habe. Oft besteht eine schnelle Lösung darin, "& callback =?" bis zum Ende einer Zeichenfolge. Manchmal muss das kaufmännische Und ein Zeichencode sein, manchmal ein "?": "? Callback =?" (siehe Forecast.io API-Verwendung mit jQuery )


6

Wenn Sie eine Chrome - Erweiterung gerade schreiben und diese Fehlermeldung erhalten, dann werden Sie sicher , haben Sie die API Basis - URL zu Ihrem hinzugefügt manifest.json‚s Berechtigungen Block , Beispiel:

"permissions": [
    "https://itunes.apple.com/"
]

6

Dies liegt an der Politik des gleichen Ursprungs . Weitere Informationen finden Sie im Mozilla Developer Network oder in Wikipedia .

Grundsätzlich müssen Sie in Ihrem Beispiel die http://nqatalog.negroesquisso.pt/login.phpSeite nur von laden nqatalog.negroesquisso.pt, nicht von localhost.


1
Aber ich muss den Webservice von einem mobilen Gerät laden, würde ich das umgehen?
Ricardo

Nun, Sie müssen einige serverseitige Änderungen vornehmen oder JSONP en.wikipedia.org/wiki/JSONP
antyrat

6

Wenn Sie unter Apache stehen, fügen Sie Ihrem Verzeichnis einfach eine .htaccess-Datei mit folgendem Inhalt hinzu:

Header set Access-Control-Allow-Origin: *

Header set Access-Control-Allow-Headers: content-type

Header set Access-Control-Allow-Methods: *

5

In Ruby on Rails können Sie Folgendes in einem Controller tun:

headers['Access-Control-Allow-Origin'] = '*'

In welchen Controller setzen Sie dies, wenn es sich um einen Ajax-Aufruf handelt? Kann ich mehr Codekontext sehen?
Rigdonmr

5

Sie können dafür sorgen, dass es funktioniert, ohne den Server zu ändern, indem Sie den Browser einschließlich des Headers erstellen Access-Control-Allow-Origin: * in die Antworten der HTTP-OPTIONEN einfügt.

Verwenden Sie in Chrome diese Erweiterung . Wenn Sie auf Mozilla sind, überprüfen Sie diese Antwort .


5

Wenn Sie dies in Angular.js erhalten, stellen Sie sicher, dass Sie Ihre Portnummer wie folgt maskieren:

var Project = $resource(
    'http://localhost\\:5648/api/...', {'a':'b'}, {
        update: { method: 'PUT' }
    }
);

Sehen Sie hier für weitere Informationen über sie.


4

Wir haben auch das gleiche Problem mit der in Chrom getesteten Phonegap-Anwendung. Ein Windows-Computer, den wir täglich vor dem Öffnen von Chrome unter der Batch-Datei verwenden. Denken Sie daran, bevor Sie dies ausführen, müssen Sie alle Chrome-Instanzen aus dem Task-Manager bereinigen, oder Sie können Chrome auswählen, um nicht im Hintergrund ausgeführt zu werden.

BATCH: (benutze cmd)

cd D:\Program Files (x86)\Google\Chrome\Application\chrome.exe --disable-web-security

1

In Ruby Sinatra

response['Access-Control-Allow-Origin'] = '*' 

für alle oder

response['Access-Control-Allow-Origin'] = 'http://yourdomain.name' 

0

Wenn Sie die Anfrage erhalten, können Sie

var origin = (req.headers.origin || "*");

als wenn du antworten musst, gehe mit so etwas:

res.writeHead(
    206,
    {
        'Access-Control-Allow-Credentials': true,
        'Access-Control-Allow-Origin': origin,
    }
);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.