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.
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.
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.
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)
}
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 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...
}
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);
}
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.
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
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
}
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 => '*', );
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 => '*';
print "Content-Type: text/turtle" print "Content-Location: mydata.ttl" print "Access-Control-Allow-Origin: *"
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
});
To CORS-enable Microsoft IIS6, perform the following steps:
Access-Control-Allow-Origin as the header name* as the header valueFor 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.
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();
});
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';
}
}
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.
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.
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:
<cfheader name="Access-Control-Allow-Origin" value="*">
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.
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>
These instance/server-level settings require OpenLink Virtuoso Open Source (VOS) 6.1.3 or later, or Virtuoso Commercial Edition 06.02.3129
* 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.comFor 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 ---
?>
For WCF service you have to develop new behavior and include it in the endpoint configuration:
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" />
Thanks for reading this post. Hoping this tutorial will help you to Enable Cross-Origin Resource Sharing.
Please give your comments and remark below.