是的,了解Laravel的都知道,在Laravel中简单的设置跨域,当然是选择barryvdh/laravel-cors这个包。起因是的,我真的是在重新发明轮子,barryvdh/laravel-cors包很优秀,但是它有很多问题。而我的新wheelmedz/cors并没有具体解决它的问题,只是顺便提一下。medz/cors包的灵感来自公司的项目。公司项目使用Laravel框架开发,前端完全分离。所以设置跨域是很有必要的,虽然传统的nginx设置跨域是可信的,但是程序设置跨域的好处是不言而喻的(可以设置多个允许跨域的域名等),并动态处理信息)。概述所有PHP项目都支持medz/cors包。你只需要一些简单的配置。这里主要先说在Laravel中的应用,因为目前内置的支持暂时对Laravel做了很好的独占处理。去友好支持以下[x]PHPNativecoding.[x]Laravel[x]PSR-7[]Symfony[]Yii2[]SlimFramework安装感谢Composer对社区做出的改变,现在我们都喜欢它,所以你只需要在你的项目中使用:composerrequiremedz/cors好的,你已经安装了它。如果你是Laravel,现在你已经在你的程序中添加了一个跨域发布的配置文件运行:phpartisanvendor:publish--provider="Medz\Cors\Laravel\Providers\LaravelServiceProvider"--force有兴趣的可以看看配置,你可以看看config/cors.php的配置。但是下面会具体说说配置。Configuration为了方便一些配置,个别bool,int,string配置可以使用.env来设置环境变量:Key描述CORS_ALLOW_CREDENTIAILSbool,设置Access-Control-Allow-Credentials为true还是falseCORS_ACCESS_CONTROL_MAX_AGEint,设置Access-Control-Max-Age值,默认为0,即关闭CORS_LARAVEL_ALLOW_ROUTE_PERFIX字符串,路由匹配方式的匹配规则,因为$request->is是用来校验的,所以可以参考请求,默认为*,代表所有路线。CORS_LARAVEL_ROUTE_GROUP_MODEbool,是否启用“单一路由中间件”或“路由中间件组”模式,默认不启用。那么所有的配置如下(建议看config/cors.php文件中各个配置的注释):关键说明allow-credentials参考CORS_ALLOW_CREDENTIAILS配置默认是['*']表示全部,你可以设置例如"'[Content-Type','X-Requested-With']"只允许上面两个头字段,这取决于你的项目。一旦出现*成员,就表示允许所有。expose-headers列出哪些标头可以作为响应的一部分在外部公开。默认值为[]。origins列出允许跨域的域名,默认为['*'],表示设置为*(只要列中出现*,就会返回*),例如设置['https://laravel-china.org'],可以设置多个,程序会自动处理。methods列出允许跨域请求的方法列表,默认为['*']代表所有方法。max-age预检请求返回的结果是否可以缓存。默认为0,表示不能缓存。单位是“秒”。您可以设置预检请求的结果允许缓存多长时间。laravel.allow-route-perfix参考CORS_LARAVEL_ALLOW_ROUTE_PERFIXlaravel.route-group-mode参考CORS_LARAVEL_ROUTE_GROUP_MODE使用其实你的Laravel程序依赖这个medz/cors,你不需要做任何代码修改,直接使用即可。因为Laravel有个神奇的特性,就是发起OPTIONS预检请求时,执行的中间件只是“全局中间件”,也就是app/Http/Kernel.php中protected$middleware设置的中间件,所以对于Laravelmedz/cors包会自动在此处添加Medz\Cors\Laravel\Middleware\Cors中间件。你发现如果你配置这个中间件,它不会执行任何其他处理。如果想自定义全局中间件的执行顺序,可以在$middleware中手动添加Medz\Cors\Laravel\Middleware\Cors。路由组模式这是解决barryvdh/laravel-cors的痛点之一,因为barryvdh/laravel-cors会在所有路由中加入跨域信息设置,实际中确实不需要,我们要的只是特定的路由组或者特定路由支持跨域请求,其他路由不能跨域请求。所以在Laravel的开发中,就有了这种模式。组模式所需的中间件称为Medz\Cors\Laravel\Middleware\ShouldGroup。为了方便,你可以在app/Http/Kernel.php的protected$routeMiddleware中给它起一个简短好记的别名,例如:protected$routeMiddleware=['cors-should'=>\Medz\Cors\Laravel\Middleware\ShouldGroup::class,];我给它取了个名字叫cors-should,现在,你可以在特定路由中设置允许跨域:Route::middleware('cors-should')->get('test-cors',function(){});当然你也可以将其用于路由组,就像上面的单路由一样,参考Laravel的Route文档。也可以直接设置到中间件组。这样只允许写中间件组的URI跨域。比如Laravel中默认的两个路由中间件组有两个组:web和api。首先,web组肯定不是我们想要的。需要跨域,api可能和前后端完全分离。前端程序不在当前API服务器的域内,导致跨域,我们可以直接设置api组,让api组跨域:protected$middlewareGroups=[///...'web'=>[//...],'api'=>[\Medz\Cors\Laravel\Middleware\ShouldGroup::class,//...],];当然,如果你为Medz\Cors\Laravel\Middleware\ShouldGroup::class设置一个路由中间件别名(例如:chors-should),你可以:protected$middlewareGroups=[///...'web'=>[//...],'api'=>['cors-should',//...],];注意,路由组模式是一种路由匹配模式,会和“配置”中的“路由匹配模式”混合使用,说到配置文件中的ENV常量CORS_LARAVEL_ALLOW_ROUTE_PERFIX或者laravel.allow-route-perfix对,就是这个路由匹配方式,默认为*匹配所有。路由匹配方式的匹配方式是使用Laravel中的Illumante\Http\Request::is方法。文档请参考Laravel请求文档,所以设置的规则与Laravel请求中is方法的要求一致。比如我们想要api前缀的路由开启跨域:那么设置为:api/*,??注意路由匹配方式如“路由组模式”中所说,匹配的是“路由组模式”。对于API,我们使用“路由组模式”只允许api中间件组的路由允许跨域,我们设置api/v2/*的“路由匹配模式”规则,则只允许api/v2/允许跨越*的路由是可以的,比如api/v1/*也是api中间件组的路由,虽然组模式匹配,但是“路由匹配模式”的规则不匹配,所以api/v1/*的路由不允许跨域信息。综上所述,medz/cors不仅仅在Laravel项目中使用,你可以在任何PHP程序中使用,但是该包只会内置预设几个主流框架的支持代码,你可以使用Array方式制作所有PHP程序支持。遗忘部分由于某些语法原因,此包只能在PHP>=7.0的版本上使用,暂时不做语法妥协。资料GitHub地址:https://github.com/medz/cors嗯,新轮子,求一波?Star。
