WCF and CORS: “No ‘Access-Control-Allow-Origin’ header is present on the requested resource”

Service-oriented ArchitectureIf you are building an Angular app (or other form of HTML5 web application) you are probably running controllers on JSON data to bind to repeaters and present to your users. In many examples, this is usually set up with static data, or a local file, but inevitably you will want to architect something a bit more scalable. One way is to introduce a WCF service to act as your gateway to a data store, but if you are running this service outside of the domain of your web application, you will see the following error in your Javascript console:

No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://www.yourdomain.com’ is therefore not allowed access.

Using a single domain

You may be tempted to solve this problem by moving the WCF service to your web application domain. By operating within the same domain, you will no longer receive the cross-domain error. However, this will tightly couple your web application and data service. If you need to access the service from a mobile app or another web application, you will run into the same problem. Centralizing your data store behind a common data service will allow for the maximum re-use across all of your applications which need to access the data.

Implementing Cross-Origin Resource Sharing (CORS)

In order to protect users while browsing the web, browsers will block AJAX requests to domains other than the originating HTML page. The CORS specification allows for applications to report to a browser if the cross-domain request can be allowed. By implementing CORS support in your WCF service, you can make your service application pass the required headers to allow for the AJAX requests from another domain to succeed.

The error message about the “Access-Control-Allow-Origin” header directly refers to these CORS headers. You can follow these simple steps to implement CORS on your RESTful WCF service.

The easy CORS fix

If you already have your WCF service up and running, as I had, the change to support GET requests is very minor. By making the following changes to the Web.config in your system.webServer section, you can get CORS headers up and running:

<httpProtocol>
	<customHeaders>
		<add name="Access-Control-Allow-Origin" value="*"/>
		<add name="Access-Control-Allow-Headers" value="Content-Type, Accept" />
		<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" />
		<add name="Access-Control-Max-Age" value="1728000" />
	</customHeaders>
</httpProtocol>

This simple change will make your error go away.

NOTE! The Access-Control-Allow-Origin setting is set to a value of “*”. This will allow all callers to have access. This is great if your service is meant to be shared with anybody, including mobile apps, or if you are controlling access to your service via a firewall. However, if you want to make sure only your web application can access, you can change this value to http://www.yourdomain.com&#8221;.

Some other good reads

In case you’re like me, you probably want to have a quick list of places to read up on the CORS WCF implementation:

  1. Cross-Domain Calls for a WCF Service
  2. Implementing CORS support in WCF
  3. RESTfull WCF Service with CORS and JQuery and Basic access authentication

 

Advertisements

6 thoughts on “WCF and CORS: “No ‘Access-Control-Allow-Origin’ header is present on the requested resource””

  1. I created a rest wcf service library. I done the same thing as you told in app.config file in stead of web.config file.I hosted this service on console application. it is working when it is directly hit in browser.but when i try to consume this sevice via jquery it is not working.I follow your step still it is not working

    1. I typically run my web services as web applications using HTTP for communication, and have not tried operating as a console application. I would recommend trying to run your service as a web app first and see if you can consume it then. If that works, you will know the issue is in the transition to your console application.

  2. I tried above method and I am still getting error XMLHttpRequest cannot load http://myserviceurl Invalid HTTP status code 405. When I tried the same thing by Adding Global.ascx to my wcf file its working. Any clue whats going on . I don’t want to add Global.ascx to my wcf service. Why doesn’t it work when I add this to web.config?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s