9

I'm trying to build a Ember app with PHP REST framework as my api locally. The Ember app is being served at http://localhost:4200 and the api is being served from just http://localhost. This is causing a CORS issue. I've tried everything that I can think of, but I keep getting an error back saying the request was blocked and that the preflight channel did not succeed. It doesn't succeed in Firefox or Chrome.

I've added the following to the .htaccess file for my api:

Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Origin "http://localhost:4200"
Header set Access-Control-Allow-Credentials true
Header set Access-Control-Allow-Headers "accept, content-type"

Here's my request headers:

Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:4200
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

And the response headers:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, content-type
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: http://localhost:4200
Connection: close
Content-Type: text/html; charset=utf-8
Date: Fri, 24 Jul 2015 17:10:49 GMT
Server: Apache/2.4.9 (Win64) PHP/5.5.12
Set-Cookie: 24fd751c8630b64fcf935a94e8bcef46=qih6pfnqo94d4cgi5b5d79h4i6; path=/
Transfer-Encoding: chunked
X-Powered-By: PHP/5.5.12
p3p: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

Any ideas or solutions? Any help is appreciated. Thanks!

NicholasJohn16
  • 2,307
  • 2
  • 16
  • 40

4 Answers4

4

Is you your preflight OPTIONS request returning 200? You can try and return a 200 response with your .htaccess like this:

Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header always set Access-Control-Allow-Origin "http://localhost:4200"
Header always set Access-Control-Allow-Credentials true
Header always set Access-Control-Allow-Headers "accept, content-type"

RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
oznu
  • 1,409
  • 2
  • 11
  • 11
  • No, it's returning 500 because of the CORS issue. I complied the js code and moved it all to the same domain and it works perfectly. The only issue is CORS. – NicholasJohn16 Aug 02 '15 at 04:41
2

One possible issue may be that the browser isn't caching the server response to the browser's OPTIONS request. To fix this, try including an "Access-Control-Max-Age" header in your response and setting it to something like '86400' (1 day). Another issue, according to MDN's documentation on CORS, may be that since you are specifying a specific origin and not just using a wildcard response for the origin, you need to include a "vary" header in your response to specify that responses from the server will depend on the origin of the request. This can be done in the response like so:

Vary: Origin

If you get a CORS error with your main request following a successful OPTIONS request, I believe you also need to include the "Access-Control-Allow-Origin" header and "Vary" header in that response as well.

Hope this helps!

  • Hi. I am using AngularJS to interact with Woocommerce API. I can get the data, but when I try a POST, I get the error `Response for preflight has invalid HTTP status code 401`. Any help is highly appreciated. – Samarth Agarwal Feb 09 '16 at 13:32
1

As this answer states, proper handling of the pre-flight OPTIONS request is necessary, but NOT SUFFICIENT for cross-site resource requests to work. All responses to any subsequent requests after prefligh must include Access-Control-Allow-Headers. Hope this helps.

Community
  • 1
  • 1
Buyuk
  • 1,054
  • 1
  • 8
  • 19
  • Thanks, but I don't have any custom headers and it doesn't even get to that point. – NicholasJohn16 Aug 02 '15 at 04:38
  • Since you don't set any custom headers why do you set access-control-allow-headers in your request? I don't see a content-type header set, so it appears it's unnecessary. – Buyuk Aug 03 '15 at 06:48
  • It is. It was just an attempt to get it working. It really shouldn't be necessary as far as I understand. – NicholasJohn16 Aug 03 '15 at 06:59
  • @NicholasJohn16 I uderstand that the request you have pasted in the question is the preflight OPTION request, or is it the original HTTP request which you are trying to send? – Buyuk Aug 03 '15 at 11:30
  • That's the preflight OPTION request. It never gets to the POST request I'm trying to send. – NicholasJohn16 Aug 03 '15 at 17:45
  • Can you provide your original request? Its more important than the preflight. – Buyuk Aug 04 '15 at 08:35
  • There is no POST request. It never gets sent because the OPTIONS request fails. – NicholasJohn16 Aug 04 '15 at 17:01
  • @NicholasJohn16 but what request are you trying to send? The problem seems to have nothing to do with the preflight, but with the request you are trying to send. – Buyuk Aug 04 '15 at 17:08
  • It's a POST request with username and password as the data. – NicholasJohn16 Aug 05 '15 at 01:38
1

In the server side servlet, add the headers and return 200 status. Example from RESTFul WCF service, where following code was added in Global.asax file

protected void Application_AuthenticateRequest(object sender, EventArgs e){
    Response.AddHeader("Access-Control-Allow-Origin", "*");
    if (Context.Request.HttpMethod.Equals("OPTIONS")) {
        Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
        Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        Response.StatusCode = (int)System.Net.HttpStatusCode.OK;
        Context.ApplicationInstance.CompleteRequest();
   }
}
Shashank Agrawal
  • 21,660
  • 9
  • 71
  • 105
Esha Wali
  • 21
  • 2