0

I have an API that fetches some date on the server.

public function post_events()
{
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: GET, POST');
    header("Access-Control-Allow-Headers: X-Requested-With");

    $city = Input::post('city','all');
    $c = Model_chart::format_chart($city);
    return $this->response($c);
}

It works fine on usual curl methods. But I am trying to access it using $http on Angular.js and it gets me this error.

XMLHttpRequest cannot load http://event.deremoe.com/vendor/events.json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://app.event.chart' is therefore not allowed access.

As you can see I already add the headers in the function. I also checked on curl and the header Access-Control-Allow-Origin is attached when I call the api.

Is there something I am missing here?

More Info: Here's the header information that is returned to me via normal curl.

Remote Address:104.28.19.112:80
Request URL:http://event.deremoe.com/vendor/events.json
Request Method:OPTIONS
Status Code:404 Not Found

Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:event.deremoe.com
Origin:http://app.event.chart
Referer:http://app.event.chart/
User-Agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36

Response Headersview source
CF-RAY:16f687416fe30c35-SEA
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html; charset=UTF-8
Date:Thu, 25 Sep 2014 10:27:17 GMT
Server:cloudflare-nginx
Set-Cookie:__cfduid=d1a9e4283faacc0a2b029efef586b6b931411640837342; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.deremoe.com; HttpOnly
Transfer-Encoding:chunked
X-Powered-By:PHP/5.4.30
Mr A
  • 1,345
  • 4
  • 22
  • 51
  • 1
    can you check the network response of ajax call if the headers are realy set ? – john Smith Sep 25 '14 at 09:58
  • @johnSmith How can I do that? ... I added the response above. – Mr A Sep 25 '14 at 09:58
  • is your ajax request cross domain? If so you'll need to use jsonp and wrap the response in the callback provided, if present so that it doesn't mess up when accessed via cURL, for it to work – martincarlin87 Sep 25 '14 at 10:04
  • @martincarlin87 How do I check? – Mr A Sep 25 '14 at 10:11
  • @MrA for example in chrome you can open developer-toolbar and then open the network tab, there you will see the request and the response, when you click on it you see the request/response headers – john Smith Sep 25 '14 at 10:19
  • a simple way to tell if it's cross domain is if the api is hosted on the same domain as the web page you are sending the ajax request from. Looking at the question, I don't think it is. – martincarlin87 Sep 25 '14 at 10:21
  • I should also add, jsonp can only be used if the response is wrapped in the callback provided so if you don't have control over the api and it's not been implemented by the api owner then you can't do it. An alternative would be to cURL it as usual and then make an ajax call to the script doing the cURL. – martincarlin87 Sep 25 '14 at 10:28
  • @martincarlin87 It's okay. I also control the server, so I can implement it if needed. But from the looks of it, it will be a very long string if done. – Mr A Sep 25 '14 at 10:30
  • I know how to send the request using jQuery but not angular, basically set the data type as jsonp and I think you can set the callback value but if not provided it's set for you. Again, I only know the normal php version and not fuel php but something like `if (isset($_REQUEST['callback'])) { echo $_REQUEST['callback'] . '(' . (json_encode($your_response) . ');'; }` – martincarlin87 Sep 25 '14 at 11:24

1 Answers1

1

The browser makes first a pre-flight options call to your api and this is what it triggers the error: Access-Control-Allow-Origin. You can create an endpoint on your api that accepts all the OPTIONS request and you have also to set the headers there like on the post events:

header('Access-Control-Allow-Origin: *');

The Status Code that you also receive is 404 Not Found. That means that is not able to find an OPTIONS endpoint.

Stavros Zavrakas
  • 3,045
  • 1
  • 17
  • 30
  • So I have to add header('Access-Control-Allow-Methods: GET, POST','OPTIONS'); ? Could you provide more explanation? – Mr A Sep 26 '14 at 01:12
  • I suppose that the piece of code that you have posted above matches an endpoint. let's assume /events with POST method is matching your function. When you are trying to do this ajax call from the browser before receiving the POST request, you will receive an OPTIONS request at /events. What you have to do in your API is to define the OPTIONS /events endpoint that will match with the following function: `public function options_events() { header('Access-Control-Allow-Origin: *'); }` – Stavros Zavrakas Sep 26 '14 at 09:33
  • take a look also here that is specific to angular: [OPTIONS-angular](http://stackoverflow.com/questions/21792759/confused-about-how-to-handle-cors-options-preflight-requests) – Stavros Zavrakas Sep 26 '14 at 09:40