Enable CORS in the Flow Framework

As you probably know, we love to use Neos in our projects. The following Flow Framework Component enabled CORS for the entire application.
If enabled, CORS (Cross-origin resource sharing) allows a web page to use resources from another domain which are usually restricted. When you develop a web application on your local machine you often need CORS even if the production web page does not.

In order to enable the component you have to edit your Settings.yaml accordingly. So you can allow CORS in development settings only if you want to. Use the environment variable of the code example or inline the value.

<?php namespace Your\Package\Name\Http; use Neos\Flow\Http\Component\ComponentChain; use Neos\Flow\Http\Component\ComponentContext; use Neos\Flow\Http\Component\ComponentInterface; /** * !!! be aware that this component enables CORS for the entire application !!! * * add this config to the Settings.yaml of your package * * Neos: * Flow: * http: * chain: * 'preprocess': * chain: * 'allowCors': * component: 'Your\Package\Name\Http\CorsComponent' * componentOptions: * origin: '%env:CORS_ORIGIN%' * * Sets the CORS headers to allow foreign origins */ class CorsComponent implements ComponentInterface { /** * @var array */ protected $options; /** * @param array $options The component options */ public function __construct(array $options = array()) { $this->options = $options; } /** * @param ComponentContext $componentContext * @return void */ public function handle(ComponentContext $componentContext) { $origin = $this->options['origin'] ?: '*'; $request = $componentContext->getHttpRequest(); $response = $componentContext->getHttpResponse(); $response->setHeader('Access-Control-Allow-Origin', $origin); $response->setHeader('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS'); $response->setHeader('Access-Control-Allow-Headers', 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'); if ($request->getMethod() === 'OPTIONS') { $response->setHeader('Access-Control-Max-Age', '1728000'); $response->setStatus(204 /* no content */); $componentContext->setParameter(ComponentChain::class, 'cancel', true); } else { $response->setHeader('Access-Control-Expose-Headers', 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'); } } }