If you do cross-domain requests from any JavaScript client to access WebEngine resources or Automation APIs, there's a chance that your browser forbids it. Since version 5.7.2, CORS allows you to communicate with Nuxeo from another domain using XMLHttpRequests
.
Nuxeo uses a filter to handle those cases. It is based on Vladimir Dzhuvinov's universal CORS filter, and allows you to configure on which URLs cross-origin headers are needed. You'll be able to configure each URL independently.
Here is a the simplest contribution, to allow cross-domain request on the whole foobar
site:
<extension target="org.nuxeo.ecm.platform.web.common.requestcontroller.service.RequestControllerService" point="corsConfig">
<corsConfig name="foobar">
<pattern>/nuxeo/site/foobar/.*</pattern>
</corsConfig>
</extension>
Configuration
Here is the list of all contribution attributes. There are all optional.
Attribute name | Description | Default value | Possible values ( "|" separates possible values) |
---|---|---|---|
allowGenericHttpRequests | If false, only valid and accepted CORS requests that be allowed (strict CORS filtering). | true | true | false |
allowOrigin | The whitespace-separated list of origins that the CORS filter must allow. |
*
| * | http://example.com http://example.com:8080 |
allowSubdomains | If true the CORS filter will allow requests from any origin which is a sub-domain origin of the allowed origins. | false | true | false |
supportedMethods | The list of the supported HTTP methods. | GET, POST, HEAD, OPTIONS | "," separates list of HTTP methods |
supportedHeaders | The names of the supported author request headers. | * | * | "," separates list of headers |
exposedHeaders |
The list of the response headers other than simple response headers that the browser should expose to the author of the cross-domain request through the XMLHttpRequest.getResponseHeader() method.
| - | "," separates list of headers |
supportsCredentials | Indicates whether user credentials, such as cookies, HTTP authentication or client-side certificates, are supported. | true | true | false |
maxAge | Indicates how long the results of a preflight request can be cached by the web browser, in seconds. | -1 | integer |
For instance, a fooly
complete contribution could looks like:
<extension target="org.nuxeo.ecm.platform.web.common.requestcontroller.service.RequestControllerService" point="corsConfig">
<corsConfig name="fooly" allowGenericHttpRequests="true"
allowOrigin="http://example.com http://example.com:8080"
allowSubdomains="true" supportedMethods="GET"
supportedHeaders="Content-Type, X-Requested-With"
exposedHeaders="X-Custom-1, X-Custom-2"
supportsCredentials="false" maxAge="3600">
<pattern>/fooly/site/.*</pattern>
</corsConfig>
</extension>
Making sure the contribution is taken into account
To debug your CORS configuration, you might use cURL
and look at the response. If you haven't blocked OPTIONS method, you should test with the preflight request for an expected POST request:
curl --verbose -H "Origin: http://www.nuxeo.com" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: X-Requested-With" -X OPTIONS http://localhost:8080/nuxeo/site/foobar/upload
With the default configuration, preflight's response must looks like:
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Access-Control-Allow-Origin: http://www.nuxeo.com
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Methods: HEAD, POST, GET, OPTIONS
< Access-Control-Allow-Headers: X-Requested-With
< Content-Length: 0
With these "Access-Control-Allow-*" headers containing expected values.