中间件/协商

实现内容协商的中间件

v2.1.1 2024-03-24 14:24 UTC

This package is auto-updated.

Last update: 2024-08-24 15:16:46 UTC


README

Latest Version on Packagist Software License Testing Total Downloads

使用 wildurand/Negotiation 实现内容协商的中间件。包含以下组件:

需求

安装

此包可通过 Composer 安装和自动加载,名称为 middlewares/negotiation

composer require middlewares/negotiation

示例

Dispatcher::run([
    new Middlewares\ContentType(),
    new Middlewares\ContentLanguage(['en', 'gl', 'es']),
    new Middlewares\ContentEncoding(['gzip', 'deflate']),
]);

ContentType

使用 Accept 头和文件扩展名检测首选 MIME 类型,并使用此值编辑头。如果缺失,也会添加 Content-Type 头到响应中。

在第一个参数中定义协商格式的优先级排序。默认使用 这些

//Use the default types
$negotiator = new Middlewares\ContentType();

//Use only few types
$negotiator = new Middlewares\ContentType(['html', 'json']);

//Use only few types and configure some of them
$negotiator = new Middlewares\ContentType([
    'html',
    'json',
    'txt' => [
        'extension' => ['txt'],
        'mime-type' => ['text/plain'],
        'charset' => true,
    ]
]);

errorResponse

如果协商没有匹配的格式,默认情况下中间件使用列表中第一个可用的格式(默认为 text/html)。使用此选项返回一个 406 错误。可选地,您可以提供一个 Psr\Http\Message\ResponseFactoryInterface,该接口将用于创建响应。如果没有定义,将使用 Middleware\Utils\Factory 自动检测。

$responseFactory = new MyOwnResponseFactory();

//Use default html format (the first provided) if no valid format was detected (By default)
$negotiator = new Middlewares\ContentType(['html', 'json']);

//Return a 406 response if no valid format was detected
$negotiator = (new Middlewares\ContentType(['html', 'json']))->errorResponse();

//Return a 406 response using a specific responseFactory if no valid format was detected
$negotiator = (new Middlewares\ContentType(['html', 'json']))->errorResponse($responseFactory);

charsets

协商中可用的字符集,通过 Accept-Charset 头。默认为 UTF-8

$negotiator = (new Middlewares\ContentType())->charsets(['UTF-8', 'ISO-8859-1']);

noSniff

添加 X-Content-Type-Options: nosniff 头,以减轻 MIME 混淆攻击。默认启用。

//Disable noSniff header
$negotiator = (new Middlewares\ContentType())->noSniff(false);

attribute

将格式名称(如 jsonhtmlcss 等)存储在 ServerRequest 的属性中。

ContentLanguage

使用 Accept-Language 头或路径前缀检测首选语言,并使用此值编辑头。如果缺失,也会添加 Content-Language 头到响应中。

第一个参数是一个数组,包含按优先级排序的可协商语言。如果没有选择其他语言进行协商,则使用第一个值作为默认值。

$request = Factory::createServerRequest('GET', '/')
    ->withHeader('Accept-Language', 'gl-es, es;q=0.8, en;q=0.7');

Dispatcher::run([
    new Middlewares\ContentLanguage(['es', 'en']),

    function ($request) {
        $language = $request->getHeaderLine('Accept-Language');

        switch ($language) {
            case 'es':
                return 'Hola mundo';
            case 'en':
                return 'Hello world';
        }
    }
], $request);

usePath

启用此选项后,将使用基本路径来检测语言。如果您为每种语言有不同的路径,则这很有用,例如 /gl/foo/en/foo

注意:路径中的语言优先于 Accept-Language 头。

$request = Factory::createServerRequest('GET', '/en/hello-world');

Dispatcher::run([
    (new Middlewares\ContentLanguage(['es', 'en']))->usePath(),

    function ($request) {
        $language = $request->getHeaderLine('Accept-Language');

        switch ($language) {
            case 'es':
                return 'Hola mundo';
            case 'en':
                return 'Hello world';
        }
    }
], $request);

redirect

用于返回一个 302 响应,重定向到包含语言的路径。这仅在启用 usePath 时有效,例如,如果请求 URI 是 /welcome,则返回重定向到 /en/welcome

$responseFactory = new MyOwnResponseFactory();

//Use not only the Accept-Language header but also the path prefix to detect the language
$negotiator = (new Middlewares\ContentLanguage(['es', 'en']))->usePath();

//Returns a redirection with the language in the path if it's missing
$negotiator = (new Middlewares\ContentLanguage(['es', 'en']))->usePath()->redirect();

//Returns a redirection using a specific response factory
$negotiator = (new Middlewares\ContentLanguage(['es', 'en']))->usePath()->redirect($responseFactory);

ContentEncoding

检测首选编码类型,通过 Accept-Encoding 头并使用此值编辑头。

$request = Factory::createServerRequest('GET', '/')
    ->withHeader('Accept-Encoding', 'gzip,deflate');

Dispatcher::run([
    new Middlewares\ContentEncoding(['gzip']),

    function ($request) {
        echo $request->getHeaderLine('Accept-Encoding'); //gzip
    }
], $request);

有关最近更改的更多信息,请参阅 CHANGELOG,有关贡献的详细信息,请参阅 CONTRIBUTING

MIT许可证(MIT)。请参阅许可证获取更多信息。