diff --git a/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/irre_tutorial/Classes/Controller/QueueController.php b/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/irre_tutorial/Classes/Controller/QueueController.php index 6dd96e729b764e9211526c6129c00df6458dd14d..991647c89c72d4b6c389aff76c3729b2039c50ba 100644 --- a/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/irre_tutorial/Classes/Controller/QueueController.php +++ b/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/irre_tutorial/Classes/Controller/QueueController.php @@ -90,13 +90,10 @@ class QueueController extends ActionController public function finishAction(): ResponseInterface { - $typoScriptFrontendController = $GLOBALS['TSFE']; - $typoScriptFrontendController->setContentType('application/json'); - $value = $this->queueService->getValues(); $this->view->assign('value', $value); $body = new Stream('php://temp', 'rw'); $body->write($this->view->render()); - return new Response($body); + return (new Response($body))->withHeader('Content-Type', 'application/json; charset=utf-8'); } } diff --git a/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_irre_foreignfield/Classes/Controller/QueueController.php b/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_irre_foreignfield/Classes/Controller/QueueController.php index c221eb3654ae5599dbfea8241f0e4e94fbbf3de1..8b518e6c6f14fbd558aa3391aadb9e849397f146 100644 --- a/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_irre_foreignfield/Classes/Controller/QueueController.php +++ b/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_irre_foreignfield/Classes/Controller/QueueController.php @@ -90,13 +90,10 @@ class QueueController extends ActionController public function finishAction(): ResponseInterface { - $typoScriptFrontendController = $GLOBALS['TSFE']; - $typoScriptFrontendController->setContentType('application/json'); - $value = $this->queueService->getValues(); $this->view->assign('value', $value); $body = new Stream('php://temp', 'rw'); $body->write($this->view->render()); - return new Response($body); + return (new Response($body))->withHeader('Content-Type', 'application/json; charset=utf-8'); } } diff --git a/typo3/sysext/extbase/Classes/Core/Bootstrap.php b/typo3/sysext/extbase/Classes/Core/Bootstrap.php index a65100315c8ad885b1cfa9bd8340ed5c31da8e11..2b9b79b8bcbe6d2986e966f8746eb27c39f5b6d8 100644 --- a/typo3/sysext/extbase/Classes/Core/Bootstrap.php +++ b/typo3/sysext/extbase/Classes/Core/Bootstrap.php @@ -176,24 +176,14 @@ class Bootstrap $this->clearCacheOnError(); } - // In case TSFE is available and this is a json response, we have - // to take the TypoScript settings regarding charset into account. - // @todo Since HTML5 only utf-8 is a valid charset, this settings should be deprecated + // In case TSFE is available and this is a json response, we have to let TSFE know we have a specific Content-Type if (($typoScriptFrontendController = ($GLOBALS['TSFE'] ?? null)) instanceof TypoScriptFrontendController - && strpos($response->getHeaderLine('Content-Type'), 'application/json') === 0 + && $response->hasHeader('Content-Type') ) { - // Unset the already defined Content-Type + [$contentType] = explode(';', $response->getHeaderLine('Content-Type')); + // Do not send the header directly (see below) $response = $response->withoutHeader('Content-Type'); - if (empty($typoScriptFrontendController->config['config']['disableCharsetHeader'])) { - // If the charset header is *not* disabled in configuration, - // TypoScriptFrontendController will send the header later with the Content-Type which we set here. - $typoScriptFrontendController->setContentType('application/json'); - } else { - // Although the charset header is disabled in configuration, we *must* send a Content-Type header here. - // Content-Type headers optionally carry charset information at the same time. - // Since we have the information about the charset, there is no reason to not include the charset information although disabled in TypoScript. - $response = $response->withHeader('Content-Type', 'application/json; charset=' . trim($typoScriptFrontendController->metaCharset)); - } + $typoScriptFrontendController->setContentType($contentType); } if (headers_sent() === false) { diff --git a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php index b2672237a7aa4a2f176fd78e8a8a157a733c30de..3e46d116c810cbeae1a572aefa81adf00d3d6ec9 100644 --- a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php +++ b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php @@ -663,7 +663,7 @@ class TypoScriptFrontendController implements LoggerAwareInterface /** * @param string $contentType - * @internal Should only be used by TYPO3 core for now + * @internal Must only be used by TYPO3 core */ public function setContentType($contentType) { @@ -1676,6 +1676,8 @@ class TypoScriptFrontendController implements LoggerAwareInterface $this->config = $cachedData['cache_data']; // Getting the content $this->content = $cachedData['content']; + // Getting the content type + $this->contentType = $cachedData['contentType'] ?? $this->contentType; // Setting flag, so we know, that some cached content has been loaded $this->cacheContentFlag = true; $this->cacheExpires = $cachedData['expires']; @@ -2374,6 +2376,7 @@ class TypoScriptFrontendController implements LoggerAwareInterface 'identifier' => $this->newHash, 'page_id' => $this->id, 'content' => $content, + 'contentType' => $this->contentType, 'cache_data' => $data, 'expires' => $expirationTstamp, 'tstamp' => $GLOBALS['EXEC_TIME'],