我已经为此工作了 24 小时,但我在 Google 上找不到任何解决方案来解决我的问题。
我正在开发一个由Laravel 4.2 API和AngularJS 1.3前端组成的网站。
我使用软件包 laravel-cors 在 Laravel 上启用了 CORS,我的请求直到昨天早上都运行良好(没有人在服务器上部署任何东西,这很奇怪)。
我在除 Firefox 以外的所有主要浏览器上都有问题,当我尝试从 Chrome/Safari/IE 访问我的 API(PUT/POST/DELETE)时,Angular 会生成一个印前检查选项请求,我收到一条 403 错误,并显示以下消息:
请求的上不存在"访问控制允许源"标头 资源。
不是我第一次看到这个,所以我检查了laravel-cors,一切似乎都很好,在Angular上也是如此,并且使用Firefox和POSTMAN(在Chrome上)它运行良好。
这是我的拉拉维尔-科尔斯配置
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(),
),
);
而在棱角方面
// Allow credentials
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.useXDomain = true;
我将Chrome和Firefox发送的请求与我的Apache网络服务器进行了比较,并使用curl重新创建了它们。
第一个来自Chrome,并返回"不允许标题"
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
如果我在 Access-Control-Request-Headers HTTP 标头中删除 accept,它运行良好,这与 Firefox 和其他浏览器不同。
这是我的Apache配置和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 *: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>
有人有想法吗?我现在被困住了。我尝试在Laravel App::before()过滤器中编写代码,但过滤器没有被触发。
PS :如果您需要测试,您可以在 http://api.roadtotark.com/auth/login :)上发送开机自检
太好了,我找到了解决方案。我禁用了 laravel-cors,并使用此配置在 public/.htaccess
中启用了跨域。
# 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}]
现在一切正常!希望这将对将来遇到相同问题的人有所帮助。
有同样的问题,我连续 2 天都面临。最后,当我将它们添加到public_html
文件夹中的.htaccess
时,这些行起到了作用:
<Limit GET POST PUT DELETE>
Allow from all
</Limit>
希望对未来的读者有所帮助!