Cross-Origin Resource Sharing (CORS)

For security reasons, browsers restrict cross-origin HTTP requests initiated within scripts. A web page can typically embed many kinds of content from other domains. However, W3C recommends that cross-origin requests for certain items (“restricted resources”) be made only using secure means. Such resources include embedded web fonts and AJAX (XMLHttpRequest) APIs.

Cross-origin resource sharing (CORS) is a mechanism that allows a browser from one domain to request restricted resources from another domain, within well-defined and secure boundaries. TDV supports CORS under Chrome and Firefox browsers, and follows the recommendation for CORS on the Web at http://www.w3.org/TR/cors/.

The administrator of a public REST service in TDV configures the CORS environment as described in this section:

CORS Configuration

Typically the client makes two kinds of requests, preflight requests and actual requests:

Preflight Requests
Testing Preflight Requests
Actual Requests
Testing an Actual Request

CORS Configuration

The TDV configures CORS using configuration parameters. The parameters are in the Administration > Configuration window under Server > Web Services Interface > CORS. These parameters are described in the following table.

Configuration Parameter

Comments

Allow Credentials

A boolean indicating whether the resource allows requests with credentials. Default value is true, because TDV always allows credentials.

When this is false, CORS is disabled.

Allowed Headers

A comma-separated list of HTTP headers that may be specified when accessing the resources. Default value is X-Requested-With, Content-Type, Accept, Origin.

Allowed Methods

A comma-separated list of HTTP methods that can be used when accessing the resources. Default list is GET, POST, HEAD.

Allowed Origins

A comma-separated list of the origins that may access the resources.
Default value is * (all origins).

Chain Preflight

If true (default), preflight requests are chained to their target resources for normal handling (that is, handling as OPTION requests). Otherwise, the filter responds to the preflight.

Exposed Headers

A comma-separated list of HTTP headers that may be exposed on the client. Default value is an empty list.

Preflight Max Age

The number of seconds that the client is allowed to cache preflight requests. Default value is 1800 seconds (30 minutes).

Preflight Requests

A preflight request asks the other domain’s server which HTTP request methods it supports. This request also asks for an indication of whether cookies or other authentication data should be sent with the actual request.

The preflight request sends its HTTP request using the OPTIONS method, to determine whether the actual request is safe to send. A preflight request is required if the actual request wants to:

Use a PUT or DELETE method
Set custom headers in the request—for example, a header such as bb

Testing Preflight Requests

You can debug CORS preflight requests using cURL.

To test a CORS preflight request

Send a preflight request using cUrl:
curl -H "Origin: http://example.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: X-Requested-With" \
-X OPTIONS --verbose \
https://www.googleapis.com/discovery/v1/apis?fields=

This is similar to a regular CORS request, with a few additions:

The -H flags send additional preflight request headers to the server.
The -X OPTIONS flag indicates that this is an HTTP OPTIONS request.
1. Optionally, use the -H flag to specify additional headers, such as User-Agent.

If the preflight request is successful, the response should include these response headers:

Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers

If the preflight request is not successful, one of the following occurs:

The three response headers listed above do not appear.
The HTTP response is not 200.

Actual Requests

An actual request includes an HTTP request method and any cookies or other authentication the other domain’s server requires. If the actual request qualifies (see list below) as a simple cross-site request, it does not need to be preceded by a preflight request.

A simple cross-site request has the following characteristics:

It uses only GET, HEAD or POST to send data to the server.
It does not set custom headers with the HTTP request.
The data sent to the other domain’s server with the HTTP request is of one of these content types:
application/x-www-form-urlencoded
multipart/form-data
text/plain

If an actual request does not qualify as a simple request, it must be preceded by a preflight request. (See Preflight Requests.)

Testing an Actual Request

You can debug actual CORS requests using cURL, using the URL you are testing in place of the sample Google API, which supports CORS.

To test an actual CORS request

Send a regular CORS request using cURL:
curl -H "Origin: http://example.com" \
https://www.googleapis.com/discovery/v1/apis?fields=

The -H "Origin: http://example.com" flag is the name of the third-party domain making the request. Substitute the name of your domain.

2. Optionally, use the --verbose flag to print the entire response so you can see the request and response headers.

The response should include the Access-Control-Allow-Origin response header.