CORS Enabled
What is CORS about?
CORS is a specification that enables truly open access across domain boundaries.
Why is CORS important?
Currently, client-side scripts (e.g., JavaScript) are prevented from accessing much of the Web of Linked Data due to "same origin" restrictions implemented in all major Web browsers.
While enabling such access is important for all data, it is especially important for Linked Open Data and related services; without this, our data simply is not open to all clients.
If you have public data which doesn't use require cookie or session based authentication to see, then please consider opening it up for universal JavaScript/browser access.
For CORS access to anything other than simple, non auth protected resources please see this full write up on Cross Origin Request Security.
How can I participate?
Granting JavaScript clients basic access to your resources simply requires adding one HTTP Response Header, namely:
Access-Control-Allow-Origin: * Access-Control-Allow-Origin: http://example.com:8080
The asterisk wild-card permits scripts hosted on any site to load your resources; listing a specific <base URI>
will permit scripts hosted on the specified site -- and no others -- to load your resources.
This is compatible with both XHR XMLHttpRequest and XDR XDomainRequest, and is supported by all the major Web browsers.
(Note that it is not possible to grant access to multiple specific sites, nor use a partial wildcard match. It is also not possible to specify more than one Access-Control-Allow-Origin header.)
At the HTTP Server level...
Security Note: The examples given below assume a wild-card '*' domain for the Access-Control-Allow-Origin header. This is provided to simplify basic use of CORS, practically meaning "I don't care how this is used." In an intranet setting, this could lead to leakage of data beyond the intranet and therefore should be avoided. In a production setting, you should take advantage of the full features of the CORS specification to make sure it does express your actual security policy. That said, in a typical Open Data situation, the wild-card can be an appropriate use of CORS.
For Apache
Apache can be configured to expose this header using mod_headers
. This is enabled by default in Apache, however you may want to ensure it's enabled in your deployment by running the following command:
a2enmod headers
To expose the header, you can add the following line inside <Directory>
, <Location>
, and <Files>
sections, or within an .htaccess
file.
<IfModule mod_headers.c> Header set Access-Control-Allow-Origin "*" </IfModule>
You can use add
rather than set
, but be aware that add
can add the header multiple times, so it's generally safer to use set
.
Finally, you may need to reload Apache to make sure your changes have been applied.
For nginx
CORS can be enabled using the Headers core module which is compiled into nginx by default:
add_header Access-Control-Allow-Origin *;
For IIS7
Merge this into the web.config
file at the root of your application / site:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> </customHeaders> </httpProtocol> </system.webServer> </configuration>
If you don't have a web.config file already, or don't know what one is, just create a new file called "web.config" containing the snippet above.
For IIS6
- Open Internet Information Service (IIS) Manager
- Right click the site you want to enable CORS for and go to Properties
- Change to the HTTP Headers tab
- In the Custom HTTP headers section, click Add
- Enter
Access-Control-Allow-Origin
as the header name - Enter
*
as the header value - Click Ok twice
For Jetty (7 and above)
Jetty 7 (starting with 7.0.0.RC2 to be exact) ships with a CrossOriginFilter
. More information...
Include the jetty-servlets
JAR into you WEB-INF/lib
and merge this into your WEB-INF/web.xml
:
<filter> <filter-name>cross-origin</filter-name> <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class> </filter> <filter-mapping> <filter-name>cross-origin</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
The CrossOriginFilter
can also be configured in the webdefault.xml to apply to all applications; the jetty-servlets
JAR is already bundled within Jetty for this use-case.
It's a simple servlet filter and should be usable in other servlet containers, such as Tomcat, JBoss AS or Glassfish.
For OpenLink Virtuoso (Basic Web Sites, Linked Data Spaces, SPARQL Endpoints, and otherwise)
- Instance/server-level settings require Virtuoso Open Source (VOS) 6.1.3 or later, or Virtuoso Commercial Edition 06.02.3129 or later.
- For older versions of Virtuoso, you can use any of the Web Application-level instructions in the following section, including the Virtuoso-specific PL (VSP). More information...
- Open up the Virtuoso Conductor's Virtual Home and Directory Admin UI
- Set the CORS options on your target virtual directory via the Cross-Origin Resource Sharing field by entering: " * " or a space-delimited list of HTTP server URIs, e.g.,
http://example.com:8080 http://blah.example.com http://foo.example.com
- Optionally hatch Reject Unintended CORS check-box, and unmatched Origins (after any header re-writing by the application itself) will be receive an empty response.
For Apache Tomcat (7.0.41 and above)
Apache Tomcat (7.0.41 onwards) ships with a Cross Origin Resource Sharing filter. Please refer documentation for more information.
The minimal configuration required to use this filter is:
<filter> <filter-name>CorsFilter</filter-name> <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> </filter> <filter-mapping> <filter-name>CorsFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
For more configuration options, refer configuration initialization parameters.
At the Web Application level...
If you can't configure the HTTP server, you can still add the necessary header through various hosting environments.
In ASP.NET
Add the the following line to your source pages.
Response.AppendHeader("Access-Control-Allow-Origin", "*");
This is compatible with IIS6, IIS7 Classic Mode, and IIS7 Integrated Mode.
In Plack Scripts
Install the Plack::Middleware::CrossOrigin module and enable it with:
enable 'CrossOrigin', origins => '*';
There are also more advanced options available.
In CGI Scripts
Just output the line
Access-Control-Allow-Origin: *
as part of your CGI script's headers.
With Perl, using CGI.pm
print header( -type => 'text/turtle', -content_location => 'mydata.ttl', -access_control_allow_origin => '*', );
With Python
print "Content-Type: text/turtle" print "Content-Location: mydata.ttl" print "Access-Control-Allow-Origin: *" print
In ExpressJS
In your ExpressJS app on nodejs, do the following with your routes
app.all('/', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "X-Requested-With"); next() });
app.get('/', function(req, res, next) { // Handle the get for this route });
app.post('/', function(req, res, next) { // Handle the post for this route })
In PHP
Add the following line to your PHP scripts --
<?php header("Access-Control-Allow-Origin: *");
As with all uses of the PHP header function, this must be done before any output has been sent from the server.
Via VSP (Virtuoso Server Page)
You can implement CORS checking through Virtuoso's built-in HTTP functions http_request_header() and http_header(). This will work with any version of Virtuoso. For example --
<?vsp IF (http_request_header (lines, 'Origin', NULL) = 'http://host.org') { http_header ('Access-Control-Allow-Origin: http://host.org\r\n'); } ELSE { RETURN; } -- Additional code here --- ?>
In Java servlets
Simply add a header to your HttpServletResponse by calling addHeader
:
response.addHeader("Access-Control-Allow-Origin", "*");
Who is doing it already?
Platforms
- Dydra
- OntoWiki (Plugin Documentation)
- OpenLink Virtuoso (Virtuoso Open Source (VOS) 6.1.3 and later, and Virtuoso Commercial Edition 06.02.3128 and later)
- Talis Platform - coming soon
Services
- DBpedia Spotlight
- Open Calais
- publishmydata.com
- sameas.org
- Uberblic - coming soon
- URIBurner.com
- Zemanta
- Helprace
- OpenStreetMap delivers map tiles with CORS headers
- Nokia Maps delivers map tiles with CORS headers
SPARQL Endpoints
- CKAN
- DBpedia and DBpedia-live
- Linked Open Commerce
- LOD Cloud Cache
- URIBurner.com
- University of Southampton - Open Data
- Muninn Project
Toolkits
- RDF::LinkedData version 0.16 and later.
- dotNetRDF Version 0.4.0 and later unless explicitly disabled by user configuration
- JSON-LD module for Drupal 7
Data Sets
- bibliographica, a catalogue of cultural works
- ckan
- catalogue.data.gov.uk
- data.gov and the new home of data.gov data
- DBpedia and DBpedia-live
- dig/csail - coming soon
- GeoNames
- productdb.org
- *.rkbexplorer.com which includes various data sets
- Semantic Web Dog Food
Ontologies
- everything at buzzword.org.uk
- FOAF
- Good Relations (GR)
- everything at ontologi.es and wiki.ontologi.es
- rdfs.org which includes SIOC, Resume-RDF and Likedis
- Vehicle Sales Ontology (VSO)
- vocab.deri.ie, all ontologies
- W3C, all ontologies - coming soon
Who still needs to get on board?
Join our effort to enable CORS on the Web by requesting that your favorite website implement it. You can follow the progress of requests sent to popular services here. Don't hesitate to join the conversations linked here, and to list the requests you've made yourself!
- purl.org -- Please see the outstanding issue.
- vocab.org and open.vocab.org
- CloudMade -- A request has been made to add CORS headers to their Mass Downloads API.
- MapQuest -- A request has been made to add CORS headers to their Open Javascript Maps API.
- Twitter -- They're willing to add CORS where they support JSONP, see the related discussion.
- Twitpic -- They've "talked about adding it in the future", but have closed the related ticket.
- Yfrog -- A request has been made to enable CORS on their API.
Who's not willing to get on board?
- Google Maps -- They won't add CORS to their API unless we find a valid use case that respect their terms of service. Offline use of maps is against section 10.1.3 of the TOS, see related discussion.