С Content-Security-Policy
Заголовки часто необходимо отправить более одного такого заголовка или объединить эти заголовки перед отправкой. Это связано с тем, что каждый модуль / пакет приложения может определять свой собственный CSP.
Сейчас у ZF3, похоже, нет способа справиться с таким сценарием. Если я пытаюсь добавить несколько заголовков CSP, они продолжают перезаписывать друг друга, так что отправляется только последний добавленный заголовок.
$headers = $controller->getResponse()->getHeaders();
$headers->addHeader(new ContentSecurityPolicy($someDirectives));
$headers->addHeader(new ContentSecurityPolicy($someOtherDirectives));
Ожидаемый результат — ответ с двумя заголовками CSP (ИЛИ объединенный CSP).
Второе дополнение перезаписывает первое, ответ содержит только один CSP.
Как я могу заставить ZF3 отправлять несколько заголовков с одинаковым именем поля?
Для получения дополнительной информации об этой проблеме, также посмотрите мою собственную проблему на github https://github.com/zendframework/zend-http/issues/159
Вы должны быть в состоянии создать простой обходной путь, используя GenericMultipleHeader в качестве ссылки (и изменение запятой на точку с запятой):
class MultiContentSecurityPolicy extends ContentSecurityPolicy implements MultipleHeaderInterface {
public static function fromString($headerLine)
{
list($fieldName, $fieldValue) = GenericHeader::splitHeaderLine($headerLine);
if (strpos($fieldValue, ';')) {
$headers = [];
foreach (explode(';', $fieldValue) as $multiValue) {
$headers[] = new static($fieldName, $multiValue);
}
return $headers;
} else {
$header = new static($fieldName, $fieldValue);
return $header;
}
}
public function toStringMultipleHeaders(array $headers)
{
$name = $this->getFieldName();
$values = [$this->getFieldValue()];
foreach ($headers as $header) {
if (! $header instanceof static) {
throw new Exception\InvalidArgumentException(
'This method toStringMultipleHeaders was expecting an array of headers of the same type'
);
}
$values[] = $header->getFieldValue();
}
return $name . ': ' . implode(';', $values) . "\r\n";
}
}
Затем используйте этот класс вместо ContentSecurityPolicy
:
$headers = $controller->getResponse()->getHeaders();
$headers->addHeader(new MultiContentSecurityPolicy($someDirectives));
$headers->addHeader(new MultiContentSecurityPolicy($someOtherDirectives));
С Зендом проверяет интерфейс, а не класс, должно работать нормально.
Это принятый стандарт HTTP, и PHP Core поддерживает это. http://php.net/manual/en/function.header.php
Если вы установите заголовки в PHP header("TESTHeader: Test1"); header("TESTHeader: Test2")
только один пройдет, и это правильно в спецификации RFC2616 Раздел 4.2 Страница 31&32
Если вы хотите отправить несколько значений, ваш заголовок должен выглядеть так: header("TESTHeader: Test1, Test2");
, хотя можно отправлять несколько заголовков с одинаковыми именами через PHP, это не рекомендуется в качестве браузеров & серверы, получающие 2 набора одного и того же заголовка, должны преобразовать их в вышеуказанный стиль, это может вызвать проблемы, так как вы не будете точно знать, в каком формате они находятся. header("TESTHeader: Test1", false); header("TESTHeader: Test2", false)
, в зависимости от соблюдения сервером или клиентами версии RFC или HTTP.
Таким образом, этот ответ является причиной того, почему вам не разрешено отправлять один и тот же заголовок несколько раз в ZF3, он не может определить, когда использовать перезапись или нет, основываясь на том, что вы установили заголовок. чтобы обойти это и использовать многозначные заголовки, которые вы можете использовать Ответ джима
Создайте свой собственный класс множественного заголовка, добавьте нужную вам функцию (MultipleHeaderInterface), затем добавьте свой заголовок во множественную группу и, наконец, вызовите его в своем
$headers = $controller->getResponse()->getHeaders();
(вызовите новую функцию с новым fromStringHeaders)