What is Cross-Origin Resource Sharing (CORS) –
Cross-origin resource sharing is fundamental that can make visible the resources which are hidden. Cross-Origin Resource Sharing (CORS) is a specification that enables truly open access across domain boundaries. CORS allows web scripts to interact more openly with content outside of the original domain, leading to better integration between web services. Cross-origin resource sharing allows blocked resources just like – fonts, on a web page to be requested from another domain outside the domain from which the resource originated.
CORS defines a way in which a browser and server can interact to determine whether or not it is safe to allow the cross-origin request. It allows for more freedom and functionality than purely same-origin requests but is more secure than simply allowing all cross-origin requests.
Why is CORS important?
JavaScript and the web programming has grown by leaps and bounds over the years, but the same-origin policy still remains. This prevents JavaScript from making requests across domain boundaries and has spawned various hacks for making cross-domain requests.
CORS introduces a standard mechanism that can be used by all browsers for implementing cross-domain requests. The spec defines a set of headers that allow the browser and server to communicate about which requests are (and are not) allowed. CORS continues the spirit of the open web by bringing API access to all.
Enable Cross-Origin Resource Sharing –
1. CORS on Apache
To add the CORS authorization to the header using Apache, simply add the following line inside either the <Directory>
,<Location>
<Files>
or <VirtualHost>
sections of your server config (usually located in a *.conf files, such as httpd.conf or apache.conf), or within a .htaccess
file:
Header set Access-Control-Allow-Origin "*"
To ensure that your changes are correct, it is strongly recommended that you use
apachectl -t
to check your configuration changes for errors. After this passes, you may need to reload Apache to make sure your changes are applied by running the command
sudo service apache2 reload
or
apachectl -k graceful
Altering headers requires the use of mod_headers. Mod_headers is enabled by default in Apache, however, you may want to ensure it’s enabled by run
a2enmod headers
Note: you can also use add
rather than set
, but be aware that add
can add the header multiple times, so it’s likely safer to use set.
2. CORS on App Engine
For Python-based applications in Google App Engine, the self.response.headers.add_header()
method can be used, such as:
class CORSEnabledHandler(webapp.RequestHandler):
def get(self):
self.response.headers.add_header("Access-Control-Allow-Origin", "*")
self.response.headers['Content-Type'] = 'text/csv'
self.response.out.write(self.dump_csv())
For Java-based applications, use resp.addHeader()
:
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
resp.addHeader("Access-Control-Allow-Origin", "*");
resp.addHeader("Content-Type", "text/csv");
resp.getWriter().append(csvString);
}
And for Go-based applications, use w.Header().Add()
:
func doGet(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Access-Control-Allow-Origin", "*")
w.Header().Add("Content-Type", "text/csv")
fmt.Fprintf(w, csvData)
}
3. CORS on ASP.NET
If you don’t have access to configure IIS, you can still add the header through ASP.NET by adding the following line to your source pages:
Response.AppendHeader("Access-Control-Allow-Origin", "*");
ASP.NET Web API
ASP.NET Web API 2 supports CORS.
To enable CORS support, add the Microsoft.AspNet.WebApi.Cors NuGet packages to your project.
Add this code to your configuration:
public static void Register(HttpConfiguration config)
{
// New code
config.EnableCors();
}
To enable cross-origin requests, add the [EnableCors] attribute to your Web API controller or controller method:
[EnableCors(origins: "http://example.com", headers: "*", methods: "*")]
public class TestController : ApiController
{
// Controller methods not shown...
}
Enabling Globally
The method described above can also be used to enable CORS across the API without annotating each controller:
public static void Register(HttpConfiguration config)
{
var corsAttr = new EnableCorsAttribute("http://example.com", "*", "*");
config.EnableCors(corsAttr);
}
4. CORS on AWS API Gateway
Amazon API Gateway adds support for CORS enabling through a simple button in the API Gateway console. Unfortunately, that button has a partial behavior, thus setting CORS correctly only for 200 answers (so not other HTTP status codes) and ignoring Jquery header support. The best solution considered so far is about avoiding to use the CORS button and set configurations manually.
This can be achieved in a couple of steps:
1. Log into API Gateway console
2. Create all the REST resources that need to be exposed with their methods before setting up CORS (if new resources/methods are created after enabling CORS, these steps must be repeated)
3. Select a resource
4. Add OPTIONS method, choose as integration type “mock”
5. For each Method of a resource
6. Go to Response Method
7. Add all the response method that should be supported (i.e. 200, 500, etc.)
8. For each response code set Response Headers to
X-Requested-With
Access-Control-Allow-Headers
Access-Control-Allow-Origin
Access-Control-Allow-Methods
9. Go to Integration Response, select one of the created response codes, then Header Mappings
10. Insert default values for headers
example:
X-Requested-With: ‘*’
Access-Control-Allow-Headers: ‘Content-Type,X-Amz-Date,Authorization,X-API-Key,x-requested-with’
Access-Control-Allow-Origin: ‘*’
Access-Control-Allow-Methods: ‘POST,GET,OPTIONS’
This operation has to be repeated for each method, including the newly created OPTIONS
11. Deploy the API to a stage
12. Check using http://client.cors-api.appspot.com/client that CORS requests have been successfully enabled
5. CORS on Caddyserver
To add the CORS authorization to the header using Caddy, simply add the following line inside your caddyfile:
cors
This will allow all resources to be accessed from every domain.
You can also be more specific, i.e. allow specific resources to specific domains:
cors /foo http://mysite.com http://anothertrustedsite.com
There are many more options you can use, here is a full example, as shown in the caddyserver docs:
cors / {
origin http://allowedSite.com
origin http://anotherSite.org https://anotherSite.org
methods POST,PUT
allow_credentials false
max_age 3600
allowed_headers X-Custom-Header,X-Foobar
exposed_headers X-Something-Special,SomethingElse
}
6. CORS in CGI Scripts
Just output the line:
Access-Control-Allow-Origin: *
.. as part of your CGI script’s headers, for example, in Perl (using CGI.pm):
print header(
-type => 'text/turtle',
-content_location => 'mydata.ttl',
-access_control_allow_origin => '*',
);
7. CORS in Perl PSGI scripts
The module Plack::Middleware::CrossOrigin provides a complete CORS server side implementation. To allow any request from any location, just add this to your builder:
enable 'CrossOrigin', origins => '*';
8. CORS in Python
print "Content-Type: text/turtle"
print "Content-Location: mydata.ttl"
print "Access-Control-Allow-Origin: *"
9. CORS on ExpressJS
In your ExpressJS app on node.js, do the following with your routes:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
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
});
10. CORS on IIS6
To CORS-enable Microsoft IIS6, perform the following steps:
- 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
11. CORS on IIS7
For Microsoft IIS7, merge this into the web.config
file at the root of your application or 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.
12. CORS on Meteor
To add CORS authorization to a Meteor application, use the webapp package’s WebApp.connectHandlers
to customize HTTP headers.
// Listen to incoming HTTP requests, can only be used on the server
WebApp.rawConnectHandlers.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
return next();
});
Use the optional path
argument to only call the handler for paths that match a specified string.
// Listen to incoming HTTP requests, can only be used on the server
WebApp.rawConnectHandlers.use("/public", function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
return next();
});
13. CORS on Nginx
The following Nginx configuration enables CORS, with support for preflight requests.
#
# Wide-open CORS config for nginx
#
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}
14. CORS in Perl PSGI scripts
The module Plack::Middleware::CrossOrigin provides a complete CORS server side implementation. To allow any request from any location, just add this to your builder:
enable 'CrossOrigin', origins => '*';
This module is also available in Debian and Ubuntu as libplack-middleware-crossorigin-perl.
15. CORS on PHP
If you don’t have access to configure Apache, you can still send the header from a PHP script. It’s a case of adding the following to your PHP scripts:
<?php
header("Access-Control-Allow-Origin: *");
Note: as with all uses of the PHP header function, this must be before any output has been sent from the server.
16. CORS on ColdFusion
If you don’t have access to configure you web server, you can still send the header from a Coldfusion script. It’s a case of adding the following to your Coldfusion scripts:
Tag Based File
<cfheader name="Access-Control-Allow-Origin" value="*">
Script Based File
var response = getPageContext().getResponse();
response.setHeader("Access-Control-Allow-Origin","*");
Note: This needs to be set before any output has been sent from the server.
17. CORS on Tomcat
Apache Tomcat includes support for CORS (Starting from Tomcat version 7.0.41).
Here is an example from those docs that demonstrates a minimal CORS configuration:
<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>
18. CORS on Virtuoso
These instance/server-level settings require OpenLink Virtuoso Open Source (VOS) 6.1.3 or later, or Virtuoso Commercial Edition 06.02.3129
- In the Virtuoso Conductor, go to Web Application Server → Virtual Domains & Directories.
- Expand the default Interface store.
- Click New Directory.
- Specify the desired Virtual Directory Type, or choose an existing virtual directory to use as a template.
- Click Next.
- Specify the Directory Path value.
- Set the CORS options.
- Cross-Origin Resource Sharing – contains a single wildcard asterisk, i.e.,
*
or an origin, such as http://example.com:8080
or http://foo.example.com
. Scripts are authorized to retrieve a resource if that resource either uses the wildcard or lists the origin of the script. For this example, enter the following single URI: http://demo.openlinksw.com
- Reject Unintended CORS check-box – when ticked and the application does not overwrite headers, unmatched Origins will be rejected by sending an empty response.
- Click Save changes.
For older versions of Virtuoso, any of the Web Application-level instructions below may be used. Any Virtuoso-based application can implement CORS checking through well-known HTTP functions http_request_header() and http_header(), 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 ---
?>
19. CORS on WCF
For WCF service you have to develop new behavior and include it in the endpoint configuration:
Create Message Inspector
public class CustomHeaderMessageInspector : IDispatchMessageInspector
{
Dictionary<string, string> requiredHeaders;
public CustomHeaderMessageInspector (Dictionary<string, string> headers)
{
requiredHeaders = headers ?? new Dictionary<string, string>();
}
public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
return null;
}
public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
var httpHeader = reply.Properties["httpResponse"] as HttpResponseMessageProperty;
foreach (var item in requiredHeaders)
{
httpHeader.Headers.Add(item.Key, item.Value);
}
}
}
Create Endpoint Behavior and use Message Inspector to add headers
public class EnableCrossOriginResourceSharingBehavior : BehaviorExtensionElement, IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
var requiredHeaders = new Dictionary<string, string>();
requiredHeaders.Add("Access-Control-Allow-Origin", "*");
requiredHeaders.Add("Access-Control-Request-Method", "POST,GET,PUT,DELETE,OPTIONS");
requiredHeaders.Add("Access-Control-Allow-Headers", "X-Requested-With,Content-Type");
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new CustomHeaderMessageInspector(requiredHeaders));
}
public void Validate(ServiceEndpoint endpoint)
{
}
public override Type BehaviorType
{
get { return typeof(EnableCrossOriginResourceSharingBehavior); }
}
protected override object CreateBehavior()
{
return new EnableCrossOriginResourceSharingBehavior();
}
}
Register new behavior in web.config
<extensions>
<behaviorExtensions>
<add name="crossOriginResourceSharingBehavior" type="Services.Behaviours.EnableCrossOriginResourceSharingBehavior, Services, Version=1.0.0.0, Culture=neutral" />
</behaviorExtensions>
</extensions>
Add new behavior to endpoint behavior configuration
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp />
<crossOriginResourceSharingBehavior />
</behavior>
</endpointBehaviors>
Configure endpoint
<endpoint address="api" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="Service.IServiceContract" />
APIs that support CORS
Libraries for implementing CORS
Thanks for reading this post. Hoping this tutorial will help you to Enable Cross-Origin Resource Sharing.
Please give your comments and remark below.