php Laravel 5.2 CORS,GET 不使用预检选项

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34748981/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 00:12:01  来源:igfitidea点击:

Laravel 5.2 CORS, GET not working with preflight OPTIONS

phplaravelcorsvue.jslaravel-5.2

提问by suncoastkid

The dreaded CORS Error:

可怕的 CORS 错误:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/mysite/api/test. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

跨域请求被阻止:同源策略不允许读取位于http://localhost/mysite/api/test的远程资源。(原因:缺少 CORS 标头“Access-Control-Allow-Origin”)。

Laravel route:

Laravel 路线:

$router->group(['prefix' => 'api', 'middleware' => 'cors'], function ($router) {
    $router->get('/test', 'MyController@myMethod');
});

Laravel Cors Middlware:

Laravel Cors 中间件:

public function handle($request, Closure $next)
    {
        header('Access-Control-Allow-Origin: *');

        // ALLOW OPTIONS METHOD
        $headers = [
            'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers' => 'Content-Type, X-Auth-Token, Origin, Authorization'
        ];
        if ($request->getMethod() == "OPTIONS") {
            // The client-side application can set only headers allowed in Access-Control-Allow-Headers
            return Response::make('OK', 200, $headers);
        }

        $response = $next($request);
        foreach ($headers as $key => $value)
            $response->header($key, $value);
        return $response;
    }

Laravel Kernel:

Laravel 内核:

 protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'cors' => \App\Http\Middleware\CORS::class
    ];

Relevant .htaccess:

相关.htaccess:

RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Relevant Vue.js:

相关Vue.js:

 new Vue({
        el: '#app',
        data: {
           //data here
        },
        http: {
            headers: {
                "Authorization": "Basic " + "apiKeyHere"
            }
        },
        methods: {
            mymethod: function (e)
            {
                e.preventDefault();
                this.$http.get('http://localhost/mysite/api/test').then(
                        function (response)
                        {
                          //do something
                        }
                )
            }
        }
    });

If I take out the Authorization header option the request works.

如果我取出 Authorization 标头选项,则请求有效。

I've also tried https://github.com/barryvdh/laravel-corsbut still no joy. Any help appreciated!

我也试过https://github.com/barryvdh/laravel-cors但仍然没有快乐。任何帮助表示赞赏!

回答by suncoastkid

Clearly not the ideal solution but it WORKS. I've added this to the top of my routes.php file:

显然不是理想的解决方案,但它有效。我已将此添加到我的 routes.php 文件的顶部:

header('Access-Control-Allow-Origin: *');
header( 'Access-Control-Allow-Headers: Authorization, Content-Type' );

It would be nice to get this working without a hack... alas.

在没有黑客的情况下让它工作会很好......唉。

UPDATE: It turned out to be IIS related. I ended up setting the headers in the web.config file and now CORS works without hacking the routes.php file.

更新:原来是 IIS 相关的。我最终在 web.config 文件中设置了标题,现在 CORS 无需破解 routes.php 文件即可工作。

<httpProtocol>
    <customHeaders>
       <add name="Access-Control-Allow-Headers" value="Origin, Authorization, X-Requested-With, Content-Type, Accept" />
       <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,PUT,DELETE" />
    </customHeaders>
</httpProtocol>

If you want to restrict access, you can add outbound rules:

如果要限制访问,可以添加出站规则:

      <outboundRules>
          <clear />
                <rule name="AddCrossDomainHeader">
                    <match serverVariable="RESPONSE_Access_Control_Allow_Origin" pattern=".*" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
                        <add input="{HTTP_ORIGIN}" pattern="(http(s)?://((.+\.)?somesite\.com|(.+\.)?anothersite\.org))" />
                    </conditions>
                    <action type="Rewrite" value="{C:0}" />
                </rule>
      </outboundRules>

回答by M Arfan

I solve my problem just adding these line on my routes.php Laravel 5.2 For greater then 5.2 in routes/web.php

我解决了我的问题,只需在我的 routes.php Laravel 5.2 上添加这些行,在 routes/web.php 中大于 5.2

header('Access-Control-Allow-Origin:  *');
header('Access-Control-Allow-Methods:  POST, GET, OPTIONS, PUT, DELETE');
header('Access-Control-Allow-Headers:  Content-Type, X-Auth-Token, Origin, Authorization');

OR register Cors middleware in global HTTP middleware stack

或在全局 HTTP 中间件堆栈中注册 Cors 中间件

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \App\Http\Middleware\CorsMiddleware::class
];

回答by Utwo

Your middleware is ok but you need to register Cors middleware in global HTTP middleware stack.

您的中间件没问题,但您需要在全局 HTTP 中间件堆栈中注册 Cors 中间件。

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \App\Http\Middleware\CorsMiddleware::class
];

回答by eithed

The issue arises from the preflight request, indeed, but the way of handling requires some additional explanation, when we're talking about Laravel - mainly OPTIONSrequest is routed (something the other answers rather do PHP way, than Laravel way), so, you have to add this to your routes for it to be successfull:

这个问题确实来自预检请求,但是处理方式需要一些额外的解释,当我们谈论 Laravel 时 - 主要是OPTIONS请求被路由(其他答案而不是 PHP 方式,而不是 Laravel 方式),所以,你必须将此添加到您的路线才能成功:

Route::options('/{any}', function(){ return ''; })->where('any', '.*');

Route::options('/{any}', function(){ return ''; })->where('any', '.*');

Now, let's cater for all other methods - create CORS middleware:

现在,让我们迎合所有其他方法 - 创建 CORS 中间件:

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, PATCH, PUT, DELETE');
    }
}

And finally, for given route, use that middleware:

最后,对于给定的路由,使用该中间件:

Route::put('/test', function(){ echo('test'); })->with('cors');

Route::put('/test', function(){ echo('test'); })->with('cors');

回答by SOUMYA

You can bypass this one without using any middleware like Barryvdh\Cors for Laravel which was not working properly with JWT AUTH , I have added the following statements in the index.php in Laravel just before the Kernel instantiation

您可以绕过这个,而无需使用任何中间件,例如用于 Laravel 的 Barryvdh\Cors,它与 JWT AUTH 无法正常工作,我在内核实例化之前在 Laravel 的 index.php 中添加了以下语句

header('Access-Control-Allow-Origin: http://localhost:8001');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token,Authorization');
header('Access-Control-Allow-Credentials: true');

add this one before

之前添加这个

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

this should work properly with JWT AUTH also. Kindly note that in Access-Control-Allow-Headers you should include Authorization otherwise your accesstoken will not be allowed with Authorization header therefore JWT AUTH will fail.Happy Coding.

这也应该与 JWT AUTH 一起正常工作。请注意,在 Access-Control-Allow-Headers 中,您应该包含 Authorization,否则您的 accesstoken 将不允许带有 Authorization 标头,因此 JWT AUTH 将失败。快乐编码。

回答by gandalf

This answer is based on this article. barryvdh/laravel-corsmiddleware library, can be used to fix the problem(Cross-Origin Resource Sharing).

这个答案是基于这篇文章barryvdh/laravel-cors中间件库,可用于解决问题(跨源资源共享)。

step 1Install it:

第 1 步安装它:

composer require barryvdh/laravel-cors

step 2Releasing vendor files of the library:

步骤 2释放库的供应商文件:

php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider"

step 3The command ran in step 2 will copy a cors.php file to config directory, which looks like this:

步骤 3在步骤 2 中运行的命令会将 cors.php 文件复制到 config 目录,如下所示:

return [

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

'supportsCredentials' => false,
'allowedOrigins' => ['*'],// ex: ['abc.com', 'api.abc.com']
'allowedHeaders' => ['*'],
'allowedMethods' => ['*'],// ex: ['GET', 'POST', 'PUT', 'DELETE']
'exposedHeaders' => [],
'maxAge' => 0,

];

For allowedOriginsthe value can either be ['*']which indicated that the origin of request can be from any domain, or an array of specific domains which can be the origins that we will allow to send request to our api, like this ['first.com', 'second.com', 'register.third.com']

因为allowedOrigins该值可以['*']表示请求的来源可以来自任何域,也可以是特定域的数组,这些域可以是我们允许向我们发送请求的来源api,如下所示['first.com', 'second.com', 'register.third.com']

and also allowedMethodscan either be ['*']or a list of allowed HTTP verbsfor instance ['POST', 'GET']

并且也allowedMethods可以是['*']或允许的列表,HTTP verbs例如['POST', 'GET']

step 4Registering the cors middleware. Open app/Http/kernel.phpand add the HandleCorsclass to $routeMiddlewarelike this:

步骤4注册cors中间件。打开app/Http/kernel.php并添加HandleCors类,$routeMiddleware如下所示:

protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'cors' => \Barryvdh\Cors\HandleCors::class, // add this line to enable cors to your routes
];

step 5Now you can add the laravel-corsmiddleware to any route that you want. For instance in Routes/api.phpI will do this:

第 5 步现在您可以将laravel-cors中间件添加到您想要的任何路由中。例如在Routes/api.php我会这样做:

Route::apiResource('category', 'CategoryController')->middleware('cors');
Route::apiResource('product', 'ProductController')->middleware('cors');

回答by Gierappa

My solution:

我的解决方案:

$router->group(['prefix' => 'api', 'middleware' => 'cors'], function ($router){
    $router->options('{param1?}/{param2?}/{param3?}', function () {});
});