18
votes

I have a website with REST Api and now I´m creating a browser extension, which will collect data from some pages and send them back to the REST Api. Because I want my extension to be compatible with both firefox and chrome, and to be easily maintainable, I´m injecting the actual code into page as a script tag, which is then executed like normal javascript. I´m currently working only on chrome version of the extension and I´ve run into a problem:

When I´m trying to send my data to the api (PATCH request), chrome won´t let me saying:

XMLHttpRequest cannot load http://my.rest/api. Origin http://website.com is not allowed by Access-Control-Allow-Origin.

I have the Access-Control-Allow-Headers, Methods and Origin all set to proper values, but it still doesn´t work. It works with GET requests though. I´ve also tried POST and PUT request but those don´t work either.

Here are my headers:

Request:

OPTIONS /some/api/path HTTP/1.1
Host: my.rest
Connection: keep-alive
Access-Control-Request-Method: PATCH
Origin: http://website.com
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
X-FireLogger: 1.1
Access-Control-Request-Headers: accept, x-http-auth-user, x-http-auth-token, origin, content-type
Accept: */*
Referer: http://website.com/index.php
Accept-Encoding: gzip,deflate,sdch
Accept-Language: cs-CZ,cs;q=0.8

Response:

Access-Control-Allow-Headers:accept, x-http-auth-user, x-http-auth-token, origin, content-type
Access-Control-Allow-Methods:PATCH
Access-Control-Allow-Origin:*
Connection:Keep-Alive
Content-Type:text/html; charset=utf-8
Date:Thu, 04 Jul 2013 10:50:08 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.2 (Win64) PHP/5.4.3
X-Frame-Options:SAMEORIGIN
X-Powered-By:Nette Framework

I´ve also tried setting Access-Control-Allow-Origin to exactly same value as Origin header, but it didn´t work. Furthemore it seems to be working in Firefox. I have Chrome 27, which should be up-to-date.

6
try adding this --disable-web-securityAhmed Ali
I´m not developing this extension for myself and I can´t ask people who wants to use it to do this.hynner
are you using jsonp?Ahmed Ali
no, I´m using CORS. You should also read this While JSONP supports only the GET request method, CORS also supports other types of HTTP requests. I need to get data to server not from server.hynner
pretty strange thing is that it works now, I´m not aware of any change in either server or client side that would cause this. It happened after chrome update to version 28, but I´m pretty sure it wasn´t working for a while in version 28.hynner

6 Answers

11
votes

I face a similar problem in node.js with CORS

You need to set the Access-Control-Allow-Origin to the specific domain not a wildcard.

Example: Access-Control-Allow-Origin to http://website.com

(You can have on your server an array of origins allowed and check against the request if it is allowed then answer with that one instead of wildcards.)

Also, you can set the Access-Control-Allow-Methods headers to a list of options like:

POST, GET, OPTIONS, DELETE, PUT
10
votes

you should allow OPTIONS in your response header..

"Access-Control-Allow-Methods ", "GET, POST,HEAD, OPTIONS,PUT, DELETE"

0
votes

I tried the CORS on Chrome 27.0.1453.116 and it worked for me. From the client side all i did is in jquery AJAX set the 'crossDomain' to true.

$.ajax('http://localhost/Elements.Services/Elements.svc/REST/Element/Get?ID=1', {
                    type: 'GET',
                    crossDomain: true,
                    success: function (data) {
                      alert(data);
                    }
                });

While on REST service side for each request set the following response headers:

  1. ("Access-Control-Allow-Headers", "Accept") or ("Access-Control-Allow-Headers", HTTPRequest.RequestedHeaders + "Accept")

  2. ("Access-Control-Allow-Methods", "POST,PUT,GET")

  3. ("Access-Control-Allow-Origin", "*")

Here is Great article on CORS working, which really helped me.

0
votes

In your WebApi:

Add the Microsoft.AspNet.WebApi.Cors NuGet package to the project

Make sure you also register CORS support either Globally, at the Controller, or at the Action.

Global - In your WebApiConfig.cs file from App_Start folder add:

public static void Register(HttpConfiguration config) {

// New code: var cors = new EnableCorsAttribute( origins: "*", headers: "*", methods: "*"); config.EnableCors(cors);

// Other configurations

}

Controller or Action - If desired/required to place support at these levels (this will overwrite global settings - Action > Controller > Config). Above Controller or Action signature:

[EnableCors(origins: "http://localhost:[*port #*]", headers: "*", methods: "*")]

Note: * are "wildcards", might want to put the domain making the request ex:(http://localhost:[port #])

Something that is very easy to miss/forget...

IN solution explorer, right-click api-project. In properties window set 'Anonymous Authentication' to Enabled !!!

0
votes

I know this is an old post but I stumbled on the same problem. The thing that solved the issue for me was uninstalling the extension I had in chrome for allowing cors before I set up cors on the backend. The extenstion can be found here: https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf?hl=en. So make sure you dont have any extensions in chrome that could mess this up.

-3
votes

why not just use PUT instead of PATCH and your request type. They pretty much do the same thing