问题
I've been on this for 24 hours, and I can't find any solution on Google for my issue.
I'm developing a website composed of a Laravel 4.2 API and an AngularJS 1.3 front-end.
I enabled CORS on Laravel with the package laravel-cors, and my requests were working well until yesterday morning (and nobody deployed anything on the server, which is weird).
I have the issue on all major browsers but Firefox, when I try to access my API (PUT/POST/DELETE) from Chrome/Safari/IE, Angular generate a preflight OPTIONS request and I get a 403 error with this message :
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Not the first time I see this, so I checked on laravel-cors, everything seems ok, on Angular too, and with Firefox and POSTMAN (on Chrome) it's working well.
Here is my laravel-cors config
return array(
'defaults' => array(
'supportsCredentials' => true,
'allowedOrigins' => array('http://localhost', 'http://example.com'),
'allowedHeaders' => array('Content-Type','X-Requested-With','accept','Origin','Access-Control-Request-Method','Access-Control-Request-Headers','Authorization'),
'allowedMethods' => array('GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'),
'exposedHeaders' => array(),
'maxAge' => 0,
'hosts' => array(),
),
);
And on the Angular side
// Allow credentials
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.useXDomain = true;
I compared the request sent by Chrome and Firefox to my Apache webserver, and I recreated them with curl.
The first one comes from Chrome, and returns "Header not allowed"
curl 'http://api.example.com' -X OPTIONS -H 'Pragma: no-cache' -H 'Access-Control-Request-Method: POST' -H 'Origin: http://example.com' -H 'Acc
ept-Encoding: gzip, deflate, sdch' -H 'Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36' -H 'Accept: */*' -H 'Cache-Control: no-cache' -H 'Referer: http://example.com/' -H 'Connection: keep-alive' -H 'Access-Control-Request-Headers: accept, content-type' --compressed
If I remove accept in the Access-Control-Request-Headers HTTP header, it's working well, and it's the difference with Firefox and the other browsers.
Here's my Apache configuration and the Laravel .htaccess
.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Virtualhost
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName api.example.com
DocumentRoot /var/www/shoptruc/api/public
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory "/var/www/shoptruc/api/public">
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
Does anyone have an idea ? I'm stuck right now. I tried to write code in Laravel App::before() filter, but the filter is not fired.
PS : If you need to test, you can send a POST on http://api.roadtotark.com/auth/login :)
回答1:
Great, I found a solution. I disabled laravel-cors and I enabled the cross-domain in public/.htaccess
with this piece of configuration.
# with AJAX withCredentials=false (cookies NOT sent)
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, PUT, OPTIONS, PATCH, DELETE"
Header always set Access-Control-Allow-Headers "X-Accept-Charset,X-Accept,Content-Type"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]]
# with AJAX withCredentials=true (cookies sent, SSL allowed...)
SetEnvIfNoCase ORIGIN (.*) ORIGIN=$1
Header always set Access-Control-Allow-Methods "POST, GET, PUT, OPTIONS, PATCH, DELETE"
Header always set Access-Control-Allow-Origin "%{ORIGIN}e"
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Allow-Headers "X-Accept-Charset,X-Accept,Content-Type"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]
Everything work well now ! Hope this will help somebody with the same issue in the future.
回答2:
Had this same problem which i faced for 2 days straight. Finally these lines did the trick when i added them to my .htaccess
in the public_html
folder:
<Limit GET POST PUT DELETE>
Allow from all
</Limit>
Hope it helps future readers!
来源:https://stackoverflow.com/questions/27796724/apache-laravel-403-forbidden-header-not-allowed