Laravel Cors(中间件不工作)

Voi*_* HD 4 php laravel

我最近尝试在Laravel 5.4中启用CORS,但不幸的是它不想工作.我已经包含了它在下面给出的代码和错误.任何人都可以帮助找出它不工作的原因吗?我已经通过了所需的标题.

我已经将域名重命名为domain.uk,仅用于示例目的,我不打算公开我的网站域名,因为它正在开发中.

路线(制定一条路线::任何用于测试目的,同时开发,通常在生产时它会发布):

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');
    });
});
Run Code Online (Sandbox Code Playgroud)

错误:

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.
Run Code Online (Sandbox Code Playgroud)

中间件:

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');
    }
}
Run Code Online (Sandbox Code Playgroud)

阿贾克斯:

function toggleDoors(roomId) {
    $.ajax({
        url: 'http://api.domain.uk/ajax/rooms/' + roomId + '/update-locked-status',
        type: "POST",
        success: function(data) {
            alert(data);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 6

请参阅https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS#Preflighted_requests_in_CORS

如果您在OPTIONS方法中遇到问题.

内核:: $ routeMiddleware在Laravel 5.4中无法使用请求方法OPTIONS,请参阅https://github.com/laravel/framework/blob/v5.4.0/src/Illuminate/Routing/RouteCollection.php#L214.要使用CORS中间件,请在Kernel :: $ middleware数组中启用它.这不好,但别无他法.

例如,我使用下一个中间件类用于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);
    }
}
Run Code Online (Sandbox Code Playgroud)

并在App\Http\Kernel中启用它

protected $middleware = [
    // ...
    \App\Http\Middleware\OptionsCorsResponse::class,
];
Run Code Online (Sandbox Code Playgroud)

起源'http://冰.域名.因此,uk'不允许访问.响应的HTTP状态代码为500.

调试代码,因为它会产生一些异常.使用任何带有OPTIONS方法的REST客户端.


Pan*_*ami 5

在 CORS 中,浏览器首先将OPTIONS请求发送到指定的路由。

在 CORS 中,发送带有 OPTIONS 方法的 preflight 请求,以便服务器可以响应是否可以使用这些参数发送请求:https : //developer.mozilla.org/en-US/docs/Web/HTTP /方法/选项

所以像这样改变你的中间件:

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');
    }
Run Code Online (Sandbox Code Playgroud)

如果您想允许其他标题到您的路由,请将它们添加到'Access-Control-Allow-Headers'标题字段中。


Mah*_*hir 5

您可以通过在 bootstrap/app.php 中添加标头来轻松完成此操作

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: *');
header('Access-Control-Allow-Headers: *');
Run Code Online (Sandbox Code Playgroud)