Laravel Cors(中间件不起作用)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43411261/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel Cors (Middleware NOT working)
提问by VoiD HD
I recently tries enabling CORS in Laravel 5.4 but unfortunately it doesn't want to work. I have included the code and the error that it's giving me below. Can anyone help finding out why it isn't working? I have passed the required headers.
我最近尝试在 Laravel 5.4 中启用 CORS,但不幸的是它不想工作。我在下面包含了代码和它给我的错误。任何人都可以帮助找出为什么它不起作用?我已经通过了所需的标题。
I have renamed my domain to domain.uk just for example purposes and I don't wan't to expose the domain of my site just yet as its under development.
我已将我的域重命名为 domain.uk 只是为了举例,我不想公开我的站点的域,因为它正在开发中。
Routes (Made the one route ::any for testing purposes while developing, usually on production it would be post):
路线(在开发时为测试目的制作了一个路线::任何,通常在生产中它会发布):
Route::group(['domain' => 'api.domain.uk', 'namespace' => 'Api'], function() {
Route::group(['middleware' => ['cors'], 'prefix' => 'call'], function() {
Route::get('/rooms/{id}/get-locked-status', 'ApiController@getRoomLockStatus');
Route::any('/rooms/{id}/update-locked-status', 'ApiController@updateRoomLockStatus');
});
});
Error:
错误:
XMLHttpRequest cannot load http://api.domain.uk/ajax/rooms/1/update-locked-status. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://ice.domain.uk' is therefore not allowed access. The response had HTTP status code 500.
Middleware:
中间件:
namespace App\Http\Middleware;
use Closure;
class Cors
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With, Application');
}
}
Ajax:
阿贾克斯:
function toggleDoors(roomId) {
$.ajax({
url: 'http://api.domain.uk/ajax/rooms/' + roomId + '/update-locked-status',
type: "POST",
success: function(data) {
alert(data);
}
});
}
ApiController:
接口控制器:
<?php
namespace App\Http\Controllers\Api;
use Auth;
use App\User;
use App\Http\Controllers\Controller;
use Validator;
use Redirect;
use Illuminate\Http\Request;
use App\Database\Frontend\Other\Rooms;
class ApiController extends Controller
{
public function getRoomLockStatus($id) {
$room = Rooms::find($id);
if ($room == null) {
return response('bad request', 400);
}
else {
return $room->rp_locked;
}
}
public function updateRoomLockStatus(Request $request, $id) {
$room = Rooms::find($id);
if ($room == null) {
return response('bad request', 400);
}
$room->rp_locked = $room->rp_locked == '1' ? '0' : '1';
$room->save();
$responseText = $room->rp_locked == '1' ?
'Your doors have been locked.' : 'Your doors have been unlocked.';
return response($responseText, 200);
}
}
回答by Sergei Belyakov
See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS#Preflighted_requests_in_CORS
请参阅https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS#Preflighted_requests_in_CORS
If your problem in OPTIONS method.
如果您的问题在 OPTIONS 方法中。
Kernel::$routeMiddleware not working in Laravel 5.4 for request method OPTIONS, see https://github.com/laravel/framework/blob/v5.4.0/src/Illuminate/Routing/RouteCollection.php#L214. For use CORS middleware, enable it in Kernel::$middleware array. It is not good, but no other way.
Kernel::$routeMiddleware 在 Laravel 5.4 中无法用于请求方法选项,请参阅https://github.com/laravel/framework/blob/v5.4.0/src/Illuminate/Routing/RouteCollection.php#L214。要使用 CORS 中间件,请在 Kernel::$middleware 数组中启用它。这不好,但别无他法。
For example, I use next middleware class for SPA and API, attention, it is not middleware 'cors' for routes
例如,我将下一个中间件类用于 SPA 和 API,注意,它不是用于路由的中间件“cors”
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
/**
* OptionsCorsResponse middleware - add CORS headers if request method OPTIONS
*/
class OptionsCorsResponse
{
/**
*
* @param Request $request
* @param Closure $next
* @return Response
*/
public function handle($request, Closure $next)
{
/* @var $response Response */
$response = $next($request);
if (!$request->isMethod('OPTIONS')) {
return $response;
}
$allow = $response->headers->get('Allow'); // true list of allowed methods
if (!$allow) {
return $response;
}
$headers = [
'Access-Control-Allow-Methods' => $allow,
'Access-Control-Max-Age' => 3600,
'Access-Control-Allow-Headers' => 'X-Requested-With, Origin, X-Csrftoken, Content-Type, Accept',
];
return $response->withHeaders($headers);
}
}
and enable it in App\Http\Kernel
并在 App\Http\Kernel 中启用它
protected $middleware = [
// ...
\App\Http\Middleware\OptionsCorsResponse::class,
];
Origin 'http :// ice . domain . uk' is therefore not allowed access. The response had HTTP status code 500.
起源'http://冰。领域 。因此,不允许访问 uk'。响应的 HTTP 状态代码为 500。
Debug your code, because it generate some exception. Use any REST client with OPTIONS method.
调试您的代码,因为它会生成一些异常。使用任何带有 OPTIONS 方法的 REST 客户端。
回答by Pankit Gami
In the CORS, browser first send the OPTIONS
request to the specified route.
在 CORS 中,浏览器首先将OPTIONS
请求发送到指定的路由。
In CORS, a preflight request with the OPTIONS method is sent, so that the server can respond whether it is acceptable to send the request with these parameters: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
在 CORS 中,发送带有 OPTIONS 方法的 preflight 请求,以便服务器可以响应是否可以使用这些参数发送请求:https: //developer.mozilla.org/en-US/docs/Web/HTTP /方法/选项
So Change your middleware like this:
所以像这样改变你的中间件:
public function handle($request, Closure $next)
{
if ($request->isMethod('OPTIONS')){
$response = Response::make();
} else {
$response = $next($request);
}
return $response
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With, Application');
}
If you want to allow other headers to your routes, please add them in the 'Access-Control-Allow-Headers'
header field.
如果您想允许其他标题到您的路由,请将它们添加到'Access-Control-Allow-Headers'
标题字段中。
回答by Marc
I ran into a sudden CORS issue recently that was not caused by CORS header configuration, I discovered the following:
我最近遇到了一个不是由 CORS 标头配置引起的突然 CORS 问题,我发现以下内容:
There are Red Herring scenarios that can also cause a CORS Cross Origin error to display and yet not have anything to do with CORS configuration, It is a result of when CORS is handled by middleware and something else prevents it from being triggered.
有一些红鲱鱼场景也可能导致显示 CORS 跨域错误,但与 CORS 配置没有任何关系,这是由于中间件处理 CORS 而其他原因阻止它被触发。
The following can indirectly cause the error to display in a browser response:
以下可能会间接导致错误显示在浏览器响应中:
- A PHP error in a Middleware class.
return $next($request);
not being fired in middleware class methodhandle
.Route::middleware
in web or api router configs reference a middleware that no longer exists or is miss spelt.- Same as above point but middleware specified in a Controller with
$this->middleware();
- 中间件类中的 PHP 错误。
return $next($request);
不会在中间件类方法中被触发handle
。Route::middleware
在 web 或 api 路由器配置中引用了一个不再存在或拼写错误的中间件。- 与上点相同,但在控制器中指定的中间件具有
$this->middleware();
Any of these can prevent a Cors middleware from ever being fired because the app exits too early and never sets the headers and thus results in a CORS error instead of a 500 Server Header error as a result of bad middleware files or bad references to middleware.
其中任何一个都可以防止 Cors 中间件被触发,因为应用程序过早退出并且从不设置标头,从而导致 CORS 错误而不是 500 服务器标头错误,因为中间件文件错误或对中间件的引用错误。
If you are certain you have configured CORS correctly then you should check your PHP error logs for Middleware errors.
如果您确定您已正确配置 CORS,那么您应该检查您的 PHP 错误日志中是否存在中间件错误。
回答by Mahfuz Shishir
You can do it easily by adding headers in bootstrap/app.php
您可以通过在 bootstrap/app.php 中添加标题来轻松完成
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: *');
header('Access-Control-Allow-Headers: *');
回答by Bimal
I am using Laravel 6 and up. This url helped me in solving my CORS issue: https://medium.com/@petehouston/allow-cors-in-laravel-2b574c51d0c1
我正在使用 Laravel 6 及更高版本。这个网址帮助我解决了我的 CORS 问题:https: //medium.com/@petehouston/allow-cors-in-laravel-2b574c51d0c1
Use this code instead of code in the url:
使用此代码而不是 url 中的代码:
<?php
namespace App\Http\Middleware;
use Closure;
class Cors
{
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type,X-Token-Auth, Authorization');
}
}
Also, if you want to use middleware through the entire application then you need to make changes in Kernel.php:
此外,如果您想在整个应用程序中使用中间件,那么您需要在 Kernel.php 中进行更改:
protected $middleware = [
\App\Http\Middleware\Cors::class, //add this line to $middleware variable
]
回答by mwx
I had a problem handling files using the withHeaders() method, so thanks to the tips below i came up with this working code:
我在使用 withHeaders() 方法处理文件时遇到了问题,所以感谢下面的提示,我想出了这个工作代码:
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->isMethod('OPTIONS'))
{
return response()->json('{"method":"OPTIONS"}', 200, $headers);
}
$response = $next($request);
$response->headers->set('Access-Control-Expose-Headers', 'Content-Disposition');
$response->headers->set('Access-Control-Allow-Origin', 'http://localhost:8080','http://localhost','https://edu.pilateswien.org');
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS');
//return $response->withHeaders($headers);
return $response;
}
回答by Pervez
Just add this code on your routes
只需在您的路线上添加此代码
header('Access-Control-Allow-Origin: http://yourdomain.com/');