JavaScript Cors Fehler => No 'Access-Control-Allow-Origin' header is present

FrazeColder

Lt. Commander
Registriert
Okt. 2013
Beiträge
1.718
Moin zusammen,

ich bekomme leider eine ungewöhnliche Fehlermeldung... Ich habe eine Ajax Request geschrieben, der auf einer Subdomain, nennen wir sie mal subdomain.example.com, funktioniert. Dieser Ajax macht einen Request an backend.example.com und dieser funktioniert auch. Hier mal der Code für diesen Request:

Code:
    var ajaxArray = {
        "fromDate": from,
        "toDate": to,
        "table": "no",
        "userID": 20
    };

console.log(ajaxArray);

jQuery.ajax({
    url: ("https://backend.example.com/api/v1/leads/show"), 
    type: "POST",
    data: ajaxArray,
    crossDomain: true,
    headers : {
    "Authorization": "Basic " + btoa("api@example.com" + ":" + "123456"), 
    "Accept": "application/json"
    },
    error: function() { alert("No"); },
    success: function(result){
        alert("Working");
    });
}});

Nun möchte ich aber einen Request von der Hauptdomain, also example.com, machen, doch das funktioniert leider nicht. Hier der Request:

Code:
    var ajaxArray = {
        "fromDate": from,
        "toDate": to
        };

    console.log(ajaxArray);

    jQuery.ajax({
        url: ("https://backend.example.com/api/v1/leads/showAdmin"), 
        type: "POST",
        data: ajaxArray,
        crossDomain: true,
        headers : {
        "Authorization": "Basic " + btoa("api@example.com" + ":" + "123456"), 
        "Accept": "application/json"
        },
        error: function() { alert("Error"); },
        success: function(result){
            alert("Working");
        });
    }});

Die Fehlermeldung ist Folgende:
Failed to load https://backend.example.com/api/v1/leads/showAdmin: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://example.com' is therefore not allowed access.

Aber in der Fehlermeldung steht ja, dass die Origin bekannt ist. Nämlich example.com, von der ja auch der Request aus funktioniert. Was mich eben wundert ist, dass es von der Subdomain aus funktioniert, aber nicht von der Hauptdomain aus... Wir kann ich das beheben? Hatte jemand schon mal diese Fehler?

Ich arbeite mit einer PHP Laravel 5.5 API und einem CORS Plugin für Laravel, welche Folgenden Einstellungen besitzt:
Code:
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Laravel CORS
    |--------------------------------------------------------------------------
    |
    | allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
    | to accept any value.
    |
    */

    'supportsCredentials' => false,
    'allowedOrigins' => ['*'],
    'allowedOriginsPatterns' => [],
    'allowedHeaders' => ['*'],
    'allowedMethods' => ['*'],
    'exposedHeaders' => [],
    'maxAge' => 0,

];

Ihr seht, 'allowedOrigins' => ['*']... Was denkst/sagt ihr?

MfG und Vielen Dank!

Update:
Code:
General:
Request URL:https://backend.example.com/api/v1/leads/showAdmin
Request Method:OPTIONS
Status Code:200 
Remote Address:94.130.239.164:443
Referrer Policy:no-referrer-when-downgrade

Response Header:
allow:POST
cache-control:private, must-revalidate
content-length:0
content-type:text/html; charset=UTF-8
date:Mon, 05 Mar 2018 13:52:41 GMT
expires:-1
pragma:no-cache
server:nginx
status:200
x-powered-by:PleskLin
x-powered-by:PHP/7.2.2

Request Header:
:authority:backend.example.com
:method:OPTIONS
:path:/api/v1/leads/showAdmin
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, br
accept-language:de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
access-control-request-headers:authorization
access-control-request-method:POST
origin:https://example.com
user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36

Die Laravel Cors Library die ich verwende ist:
https://github.com/asm89/stack-cors
 
Zuletzt bearbeitet:
Versuch mal

Code:
'allowedOrigins' => array('*')
 
Zuletzt bearbeitet von einem Moderator:
Nein, von der Domain von der es aus funktioniert, diese lautet partner.example.com. Und wo soll ich den Code von Dir einfügen?

Habe gerade mal noch meine Frage geupdatet ;)
 
Hmm, in der Doku ist es anders aufgebaut, als du es hast:

Code:
<?php

use Asm89\Stack\CorsService;

$cors = new CorsService(array(
    'allowedHeaders'         => array('x-allowed-header', 'x-other-allowed-header'),
    'allowedMethods'         => array('DELETE', 'GET', 'POST', 'PUT'),
    'allowedOrigins'         => array('localhost'),
    'allowedOriginsPatterns' => array('/localhost:\d/'),
    'exposedHeaders'         => false,
    'maxAge'                 => false,
    'supportsCredentials'    => false,
));

$cors->addActualRequestHeaders(Response $response, $origin);
$cors->handlePreflightRequest(Request $request);
$cors->isActualRequestAllowed(Request $request);
$cors->isCorsRequest(Request $request);
$cors->isPreflightRequest(Request $request);

Deine Config ist aufgebaut, wie die von dem Plugin, was ich gepostet habe. Ich vermute, dass demnach gar keine Konfiguration vorgenommen wird.
 
Das (CORS) funktioniert mit "allowedHeaders: *" nicht!
Auf die OPTIONS Anfrage, muss vom Server entsprechend geantwortet werden.
OPTIONS fragt im header field "HTTP_ACCESS_CONTROL_REQUEST_HEADERS" an, ob der zusätzliche Header "authorization" (und ggf. weitere, Komma separiert) erlaubt ist, daraufhin müssen diese auch vom Server / dem Endpunkt deiner API entsprechend beantwortet werden. Wildcards sind da nicht erlaubt. Warum auch immer es so viele Beispiele im Internet damit gibt: Die sind alle falsch.

Auf deinen oben gezeigten Request muss mit

PHP:
$cors = new CorsService(array(
    'allowedHeaders'         => array('authorization'),
    'allowedMethods'         => array('POST'),
    'allowedOrigins'         => array('*'),
    'allowedOriginsPatterns' => array(),
    'exposedHeaders'         => false,
    'maxAge'                 => false,
    'supportsCredentials'    => false,
));

geantwortet werden.
 
Funktioniert leider immer noch nicht... Selber Fehler wie vorher..
 
Wenn der Response-Header von oben stimmt, dann wird deine Laravel-Middleware für den OPTIONS-Request nicht gefeuert.
Jedenfalls wird ja kein "Access-Control-Allow-Origin" und "Access-Control-Allow-Methods" und "Access-Control-Allow-Headers" im Response zurück geliefert.
 
Wie kann ich das aktivieren/einstellen? (Ist mein erstes Projekt in Laravel)
 
Keine Ahnung, ich verwende das Slim Framework für meine PHP-Applikationen :D
 
Moin zusammen, da mein neuer Thread leider gesperrt wurde, hier nochmal ein Update:

Leider existiert das Problem immer noch.. Habe nun dieses Plugin für die CORS verwendet:
https://github.com/barryvdh/laravel-cors

Response und Request Header sehen immer noch gleich aus, Cors Einstellungen sehen wie Folgt aus:
Code:
<?php
 
return [
 
    /*
    |--------------------------------------------------------------------------
    | Laravel CORS
    |--------------------------------------------------------------------------
    |
    | allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
    | to accept any value.
    |
    */
 
    'supportsCredentials' => false,
    'allowedOrigins' => ['*'],
    'allowedOriginsPatterns' => [],
    'allowedHeaders' => ['*'],
    'allowedMethods' => ['*'],
    'exposedHeaders' => [],
    'maxAge' => 0,
 
];

In der Datei App\Http\Kernel.php habe ich ebenfalls, wie ganz unten auf der Seite vom CORS Plugin CSRF Tokens deaktiviert und auch für die Middelware die HandleCors registriert:

Code:
/**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\TrustProxies::class,
		\Barryvdh\Cors\HandleCors::class,
    ];
 
    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            //\App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
 
        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

Was denkt Ihr, woran liegt es? Ich finde den Fehler leider nicht und verstehe auch nicht, wieso es auf der einen Unterseite funktioniert, allerdings auf der Hauptdoamin nicht?

Ich würde mich sehr über Hilfe freuen.
Mit freundlichen Grüßen und Vielen Dank
 
Prüfe mal folgendes:
* Ist die Request-Methode OPTIONS an all deinen Endpunkten gebunden? Erledigt das die Middleware für dich?
* Check nochmal genau die Request und Response Header
* Stimmt die Authentifizierung...

Ich verwende zum Beispiel keine "Middleware" für die Options-Requests sondern...

PHP:
<?php
/**
 * Auf dieses Skript wird in der Serverkonfiguration hin umgeleitet, 
 * wenn ein CORS (Cross-Origin Resource Sharing  / Cross Domain) Request via Javascript
 * Ausgelöst wird. Dabei wird mit der Anfragemethode OPTIONS abgefragt, 
 * ob zusätzliche Header und die eigentliche 
 * Request-Methode erlaubt sind.
 *
 * @author <Ayngush>
 * @version 1.0
 */
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS');
header('Access-Control-Max-Age: 0');

if (array_key_exists('HTTP_ACCESS_CONTROL_REQUEST_HEADERS', $_SERVER)) {
    header('Access-Control-Allow-Headers: '.$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']);
} else {
    header('Access-Control-Allow-Headers: X-Requested-With, Origin, Authorization, Accept');
}

if (strtoupper($_SERVER['REQUEST_METHOD']) === "OPTIONS") {
    echo 'API CORS-Support Skript Version 1.0';
    exit;
}

Vereinfachter Auszug aus der Apache-Config:

Code:
<VirtualHost *:443>
    ServerName api.example.com

    ...

    <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteCond %{REQUEST_METHOD} OPTIONS
        RewriteRule .* /cors.php [L]

        RewriteCond %{REQUEST_METHOD} !^(GET|POST|HEAD|PUT|PATCH|DELETE)$
        RewriteRule .* - [F]
    </IfModule>

    ...

</VirtualHost>
 
Zuletzt bearbeitet:
Zurück
Oben