TYPO3:无Response对象时在Powermail Finisher中添加HTTP响应头
在Powermail Finisher中添加HTTP限流响应头的解决方案
由于TYPO3采用HTTP中间件架构,直接调用header()函数会绕过PSR-7响应机制导致失效,你可以通过请求属性传递+自定义中间件的方式实现需求,具体步骤如下:
1. 编写自定义中间件处理响应头
创建一个中间件类,负责从请求属性中提取限流头信息并添加到最终响应里:
<?php namespace YourVendor\YourExtension\Middleware; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; class RateLimitHeaderMiddleware implements MiddlewareInterface { public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { // 先让请求继续处理 $response = $handler->handle($request); // 从请求属性中取出预定义的限流头 $rateLimitHeaders = $request->getAttribute('rateLimitHeaders', []); foreach ($rateLimitHeaders as $headerName => $headerValue) { $response = $response->withHeader($headerName, $headerValue); } return $response; } }
2. 注册中间件
在Configuration/RequestMiddlewares.php中注册这个中间件,确保它在响应输出前执行:
return [ 'frontend' => [ 'your-vendor/your-extension/rate-limit-header' => [ 'target' => \YourVendor\YourExtension\Middleware\RateLimitHeaderMiddleware::class, 'after' => [ 'typo3/cms-frontend/prepare-tsfe', ], 'before' => [ 'typo3/cms-frontend/output-compression', ], ], ], ];
3. 在Powermail Finisher中传递限流头信息
在你的自定义Finisher里,将限流头信息存入当前请求的属性中:
<?php namespace YourVendor\YourExtension\Finisher; use In2code\Powermail\Domain\Finisher\AbstractFinisher; use TYPO3\CMS\Core\Utility\GeneralUtility; use Psr\Http\Message\ServerRequestInterface; class RateLimitFinisher extends AbstractFinisher { public function execute() { // 获取当前请求对象 $request = $GLOBALS['TYPO3_REQUEST'] ?? GeneralUtility::makeInstance(\TYPO3\CMS\Core\Http\RequestFactory::class)->createServerRequestFromGlobals(); // 定义限流头内容 $rateLimitHeaders = [ 'X-RateLimitLimit' => '5', 'X-RateLimitRemaining' => '4', 'X-RateLimitReset' => (string)(time() + 3600) ]; // 将头信息存入请求属性 $updatedRequest = $request->withAttribute('rateLimitHeaders', $rateLimitHeaders); // 更新全局请求对象,确保中间件能读取到 $GLOBALS['TYPO3_REQUEST'] = $updatedRequest; } }
关键说明
- 这种方式完全遵循TYPO3的PSR-7响应机制,避免了直接调用
header()的兼容性问题 - 中间件会在整个请求流程的后期执行,确保所有业务逻辑(包括Finisher)完成后再添加响应头
- 如果需要动态计算限流值,直接在Finisher中更新
$rateLimitHeaders数组即可
内容的提问来源于stack exchange,提问作者cweiske
相关产品推荐
相关产品推荐

