werk365 / etagconditionals
Laravel 包,用于启用对 ETags 的支持,并处理 If-Match 和 If-None-Match 条件请求
Requires
- illuminate/support: ~7|~8|~9|~10
Requires (Dev)
- orchestra/testbench: ~5|~6|~7|~8
- phpunit/phpunit: ~8.0|~9.0
This package is auto-updated.
Last update: 2024-09-22 13:48:41 UTC
README
此包提供了一套中间件,用于设置 ETags 并处理 HTTP 条件请求。
目前支持 If-None-Matched
和 If-Match
。
该包旨在提供工具,以在用 Laravel 构建API时提供更好的客户端缓存,以及防止空中碰撞。
当使用此包并启用中间件时,您的客户端(浏览器)将自动处理由 ETag
和 If-None-Match
标头提供的缓存。
安装
通过 Composer
$ composer require werk365/etagconditionals
用法
您可以使用中间件组,自动应用所有可用中间件(例如,如果您使用 apiResource 路由,则推荐这样做),通过设置 etag
中间件,或单独应用中间件。
当前可用中间件
setEtag
ifMatch
ifNoneMatch
setEtag
方法:任何
此中间件将在您的响应上设置 ETag
标头。 ETag
标头等于 $response->getContent()
的 md5 哈希。 支持通过将请求转换为 GET
请求并更改响应来处理 HEAD
请求。
ifMatch
方法:PATCH
此中间件将创建一个新请求到端点的 GET
等效项,并检索当前内容。之后,将比较当前内容的哈希和 If-Match
哈希。如果哈希匹配,则通过中间件允许 PATCH
请求,如果不匹配,则返回 412
。
重要 由于内部创建的
GET
请求也将通过启用的中间件,您可能会遇到一些问题。例如:如果您有一个未应用于If-Match
etag 所属的响应体的中间件,这将导致哈希不匹配。对于此场景,此中间件设置一个
X-From-Middleware: IfMatch
标头,您可以在其他中间件中使用它来过滤这些请求。请注意,由于此标头也可能由客户端设置,因此永远不要用它来跳过重要操作,如身份验证中间件。
ifNoneMatch
方法:GET|HEAD
此中间件将简单地比较提交的 If-None-Match
标头与响应的新创建的 etag。如果没有匹配,则返回 200
,在 GET
请求的情况下返回新的响应。如果哈希匹配,则返回 304
,不带内容,允许浏览器使用缓存的内容。
比较算法
默认情况下,将使用弱比较算法为 IfMatch
和 IfNoneMatch
ETags。在实践中,这意味着我们简单地从 ETag 中删除任何 W/
标签,以便它们可以与中间件中创建的正常标签进行比较。这是为了支持某些配置自动将 W/
标签添加到我们提供的 ETag 的情况。
可以通过发布配置文件来更改此行为
$ php artisan vendor:publish --provider="Werk365\EtagConditionals\EtagConditionalsServiceProvider"
然后更改以下值
return [ 'if_match_weak' => env('IF_MATCH_WEAK', true), 'if_none_match_weak' => env('IF_NONE_MATCH_WEAK', true), ];
或者通过设置上面的ENV值。
定义自定义ETags
静态方法 EtagConditionals::etagGenerateUsing()
允许您通过传递回调函数作为参数,完全控制ETag的生成方式。这意味着您可以使用不同的算法返回ETag,或者采用其他自定义解决方案。
EtagConditionals::etagGenerateUsing(function (\Symfony\Component\HttpFoundation\Response $response) { return hash('sha256', $response->getContent()); });
EtagConditionals::etagGenerateUsing(function (\Illuminate\Http\Request $request, \Symfony\Component\HttpFoundation\Response $response) { return Cache::rememberForever('etag.'.$request->url(), function () use ($response) { return md5($response->getContent()); }); });
变更日志
请参阅变更日志,了解最近的变化信息。
贡献
请随时创建问题和提交pull请求。对于提交的任何PR,请确保它已通过测试或包括新的测试。
安全
如果您发现任何与安全相关的问题,请通过作者电子邮件联系,而不是使用问题跟踪器。
致谢
许可
请参阅许可文件获取更多信息。