alpshq / statamic-cache-evader

Statamic 插件,帮助您绕过静态缓存并在缓存页面支持表单。

安装: 123

依赖关系: 0

建议者: 0

安全性: 0

星标: 4

关注者: 1

分支: 0

开放问题: 2

类型:statamic-addon

v1.4.1 2022-05-12 20:54 UTC

This package is auto-updated.

Last update: 2024-09-21 18:44:44 UTC


README

缓存绕过

Statamic 3 的缓存绕过

此插件提供了多种简单的方法来在缓存页面中提供 未缓存内容,并使在缓存页面上使用 Statamic 表单成为可能。

您可以做什么

支持

如果您喜欢这个插件,请考虑关注我的Twitter。如果您有功能请求,请随时通过打开GitHub问题来发起讨论。如果您有任何进一步的问题或想与我讨论合作机会,请给我发邮件到hello@jakub.io

安装

您可以使用 composer 安装此插件

composer require alpshq/statamic-cache-evader

或者,您可以通过导航到控制面板中的Statamic 市场place并搜索 Cache Evader 来安装插件。

用法:基于 HTTP GET 参数的缓存绕过

基本上,您可以在任何URL中添加带有 任何 值的 GET 参数 _nc 来绕过缓存。

修改器

要添加相应的 HTTP 参数名称到任何URL,您可以使用内置的修改器 evade_cache

<a href="{{ current_url | evade_cache }}">Link to current (uncached) URL</a>

缓存绕过是如何工作的?

  • 插件将用插件的 StaticCache 中间件替换 Statamic 的默认缓存中间件。
  • 替换的中件将检查请求中是否包含缓存绕过参数。如果找到参数,则绕过缓存。如果没有,则应用 Statamic 的默认行为。

用法:表单

为了使您的表单在缓存环境中正常工作,请确保在关闭 </body> 标签之前添加 {{ cache_evader_scripts }} 标签。您可以在包含表单的每个页面上添加它,或者将其添加到全局布局中。

<!doctype html>
<html>
    <head>
        ...
    </head>
    <body>
        {{ template_content }}
        ...
        {{ cache_evader_scripts }}
    </body>
</html>

此标签将加载一个脚本,该脚本将为所有表单添加一个名为 _xsrf_token 且值为 XSRF cookie 的隐藏输入字段。

SpoofXsrfHeader 中间件将确保添加的字段被默认的 Laravel CSRF 保护中间件验证。

为了为用户提供有意义的错误和成功消息,您需要确保表单重定向到 未缓存 页面。在您的表单中添加包含前面提到的缓存绕过 HTTP 参数的 _redirect_error_redirect 链接。最简单的方法是使用 evade_cache 修改器。

{{ form:create handle="contact-form" }}
    <input type="hidden" name="_redirect" value="{{ current_url | evade_cache }}" />
    <input type="hidden" name="_error_redirect" value="{{ current_url | evade_cache }}" />
    <!-- Your fields, buttons, success & error messages ... --> 
{{ /form:create }}

提交后,上述表单将重定向您到当前页面的未缓存版本,显示所有动态内容,例如错误和成功消息。

就是这样。您的表单将像没有缓存一样工作。

它具体是如何工作的?

  • 您使用{{ cache_evader_scripts }}标签引入的脚本,该脚本会遍历所有表单,并通过添加一个名为_xsrf_token的隐藏输入字段,将当前的XSRF-TOKENcookie值附加到表单中。
  • 如果没有这样的cookie存在(尤其是在您使用full缓存策略,并且当前用户由静态文件缓存提供服务时,这种情况尤为常见)
    • 脚本将对cache-evader.ping路由(/cache-evader/ping)发起一个轻量级的fetch请求。
    • Laravel将响应并附带XSRF-TOKENcookie。
    • 所有后续的访问和请求都可以访问到XSRF-TOKENcookie,并且不会再次发起fetch请求。
  • SpoofXsrfHeader中间件将请求的x-xsrf-token头填充为_xsrf_token字段的值。它基本上复制了当前的SPA行为,这在Laravel文档中有所提及。灵感来自Laravel的表单方法欺骗

用法:将未缓存的组件作为缓存页面的部分注入

如果您能够在页面上显示动态内容的同时利用Statamic的完整缓存策略,那不是很好吗?

无需再寻找——您已经找到了解决方案。借助您缓存页面中的未缓存组件,您可以同时享受两者之所长。

设置方法

要启用自定义组件的注入,请确保在</body>标签之前添加{{ cache_evader_scripts }}标签。您可以在使用{{ cache_evader_partial }}标签的每个页面上添加它,或者将其添加到全局布局中。

<!doctype html>
<html>
    <head>
        ...
    </head>
    <body>
        {{ template_content }}
        ...
        {{ cache_evader_scripts }}
    </body>
</html>

该标签将加载一个脚本,通过为每个组件发送立即的fetch请求来获取您未缓存的组件的内容。fetch请求将绕过缓存并加载您在组件中指定的任何动态内容。

基本用法

首先,创建一个包含动态内容的简单组件:partials/user.antlers.html

<!-- Your partial with dynamic content -->
{{ if logged_in }}
    Welcome {{ current_user:email }}
{{ else }}
    Please login.
{{ /if }}

现在,只需在模板中使用{{ cache_evader_partial }}标签包含该组件即可。

<!-- Your template -->
{{ cache_evader_partial:user }}
<!--                    ^^^^ -> This is the file name of the partial. -->

就是这样。您的完全缓存的页面现在将始终显示用户的电子邮件!

参数

您可以在组件中添加任意数量的参数。您可以在组件中作为常规变量访问这些参数。

重要
请注意,参数是公开可见的——不要使用参数共享机密!

<!-- Your partial with dynamic content -->
{{ if logged_in }}
    Welcome {{ current_user:email }}
{{ else }}
    Please <a href="{{ login_url }}">login</a>.
{{ /if }}
<!-- Your template -->
{{ cache_evader_partial:user login_url="/login" }}

显示加载消息

您可以通过将加载指示器包裹在标签对中来显示加载消息或指示器。

<!-- Your template -->
{{ cache_evader_partial src="user" login_url="/login" }}
    Loading login state ...
{{ /cache_evader_partial }}

占位符元素

当您使用{{ cache_evader_partial }}标签包含组件时,将渲染一个占位符div而不是组件。占位符最终将被组件的内容替换。

您可以通过添加一个wrap参数来更改占位符:{{ cache_evader_partial src="..." wrap="span" }}

包装组件内容

组件的内容将包装在div元素中。您可以通过在组件中渲染单个根元素来避免这种行为。

这将包裹在div

<span>
    Welcome {{ current_user:email }}!
</span>
<a href="{{ logout_url }}">Not {{ current_user:email }}?</a>

这将不会包裹在div

<p>
    <span>
        Welcome {{ current_user:email }}!
    </span>
    <a href="{{ logout_url }}">Not {{ current_user:email }}?</a>
</p>

脚本标签

是的!您可以在您的部分中包含脚本标签。它们将被执行。

<!-- Your partial with dynamic content -->
{{ if logged_in }}
    Welcome {{ current_user:email }}
{{ else }}
    Please <a href="{{ login_url }}">login</a>.
{{ /if }}

<script src="{{ mix src='/js/user.js' }}"></script>

JavaScript 插件

在发送 fetch 请求之前

在将每个 fetch 请求发送到您的服务器之前,在占位符元素上触发 cacheEvaderBeforeInject 事件。您可以通过在事件上调用 preventDefault() 来取消 fetch 请求。

window.addEventListener('cacheEvaderBeforeInject', ev => {
  ev.preventDefault(); // No fetch request is sent.
  // ev.target -- The placeholder element
  // ev.detail -- See below which properties are available. 
});

事件将有一个 detail 属性,其中包含请求发送到的 URL 以及您提供给部分的全部参数。

内容注入之后

在您的部分动态内容被检索并注入到 DOM 之后,在注入元素上触发 cacheEvaderAfterInject 事件。

window.addEventListener('cacheEvaderAfterInject', ev => {
  // ev.target -- See below what the target will be.
  // ev.detail -- See below which properties are available.
});

事件 target 的值将是您的部分的外部包装元素。如果您的部分只有一个根元素,则 target 的值将是您的根元素。否则它将是一个包装 div

事件将有一个 detail 属性,其中包含请求发送到的 URL、您提供给部分的全部参数以及服务器的响应。

动态部分是如何详细工作的?

  • 当使用 {{ cache_evader_partial }} 标签时,将渲染一个不带实际内容的占位符。
  • 您使用 {{ cache_evader_scripts }} 标签添加到浏览器中的 JavaScript 将遍历每个占位符,并向服务器发送 fetch 请求
  • 您的服务器渲染部分并将其发送到浏览器
  • 占位符将被实际内容替换

配置

您可以将配置文件发布以修改默认参数名称(_nc)和默认值(!

php artisan vendor:publish --tag=cache-evader-config

您可以在 config/statamic/cache-evader.php 中找到已发布的 配置文件 - 查看它以了解各种选项的解释。

安全性

如果您遇到任何与安全相关的问题,请直接通过电子邮件联系 jakub@alps.dev 而不是打开一个问题。所有与安全相关的问题都将得到及时解决。

许可

MIT -- 请参阅 许可文件