Cross-Origin Resource Sharing (CORS)

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:

Simplest contribution

  <extension target="org.nuxeo.ecm.platform.web.common.requestcontroller.service.RequestControllerService" point="corsConfig">
    <corsConfig name="foobar">


Here is the list of all contribution attributes. There are all optional.

Attribute nameDescriptionDefault valuePossible values ( "|" separates possible values)
allowGenericHttpRequests If false, only valid and accepted CORS requests that be allowed (strict CORS filtering). truetrue | false
allowOrigin The whitespace-separated list of origins that the CORS filter must allow. * * |
allowSubdomains If true the CORS filter will allow requests from any origin which is a sub-domain origin of the allowed origins. falsetrue | false
supportedMethodsThe list of the supported HTTP methods.GET, POST, HEAD, OPTIONS"," separates list of HTTP methods
supportedHeadersThe 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. truetrue | false
maxAge Indicates how long the results of a preflight request can be cached by the web browser, in seconds. -1integer

For instance, a fooly complete contribution could looks like:

Fooly contribution

      <extension target="org.nuxeo.ecm.platform.web.common.requestcontroller.service.RequestControllerService" point="corsConfig">
        <corsConfig name="fooly" allowGenericHttpRequests="true"
          allowSubdomains="true" supportedMethods="GET"
          supportedHeaders="Content-Type, X-Requested-With"
          exposedHeaders="X-Custom-1, X-Custom-2"
          supportsCredentials="false" maxAge="3600">

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:

Simulate preflight request

curl --verbose -H "Origin:" -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:

Default response

< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Access-Control-Allow-Origin:
< 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.

a month ago Andrew Goodricke Syntax error fixed
3 years ago Solen Guitter 23
3 years ago Frantz Fischer 24
3 years ago Frantz Fischer 22 | Reverted from v. 19
3 years ago Frantz Fischer 21
3 years ago Frantz Fischer 20
6 years ago Arnaud Kervern 19
6 years ago Solen Guitter 18
6 years ago Arnaud Kervern 16
6 years ago Arnaud Kervern 17
6 years ago Arnaud Kervern 15
6 years ago Solen Guitter 14 | Added Since 5.7.2
6 years ago Florent Guillaume 12
6 years ago Florent Guillaume 13
6 years ago Solen Guitter 11 | Fixed typos
6 years ago Arnaud Kervern 9
6 years ago Arnaud Kervern 10
6 years ago Arnaud Kervern 8
6 years ago Arnaud Kervern 7
6 years ago Arnaud Kervern 5
6 years ago Arnaud Kervern 6
6 years ago Arnaud Kervern 4
6 years ago Arnaud Kervern 2
6 years ago Arnaud Kervern 3
6 years ago Arnaud Kervern 1
History: Created by Arnaud Kervern

We'd love to hear your thoughts!

All fields required