12

I am currently reading through "Pro AngularJS" by Adam Freeman. In going through the examples, he has the reader create a sports store app using Angular (of course) with a Deployd server resource. The Deployd resource is set up to return JSON data that is to be populated into the model. I am using NodeJS to run my server. It is currently setup on port 5000 (http://localhost:5000/sportsstore/app.html). The Deployd resource is running on port 5500 (http://localhost:5500/products). When hitting Deployd, the response is as follows:

[
    { "name": "Kayak", "description": "A boat for one person", "category": "Watersports", "price": 275, "id": "a1c999fc248b2959" },
    { "name": "Lifejacket", "description": "Protective and fashionable", "category": "Watersports", "price": 48.95, "id": "61303717cfad182e" },
    { "name": "Soccer Ball", "description": "FIFA-approved size and weight", "category": "Soccer", "price": 19.5, "id": "0fb5f67bdcbd992f" },
    { "name": "Corner Flags", "description": "Give your playing field a professional touch", "category": "Soccer", "price": 34.95, "id": "24385d315dd388b4" },
    { "name": "Stadium", "description": "Flat-packed 35,000-seat stadium", "category": "Soccer", "price": 79500, "id": "500fb6805905a856" },
    { "name": "Thinking Cap", "description": "Improve your brain efficiency by 75%", "category": "Chess", "price": 16, "id": "637d8a1f42e6fa1c" },
    { "name": "Unsteady Chair", "description": "Secretly give your opponent a disadvantage", "category": "Chess", "price": 29.95, "id": "73393312ec7dfab7" },
    { "name": "Human Chess Board", "description": "A fun game for the family", "category": "Chess", "price": 75, "id": "7871d02a662b0915" },
    { "name": "Bling-Bling King", "description": "Gold plated, diamon-studded King", "category": "Chess", "price": 1200, "id": "b59a3389a0e248bd" }
]

I am attempting to retrieve this data through use of $http.get:

$http.get("http://localhost:5500/products")
    .success(function (data) { ... })
    .error(function (error) { ... });

However, this keeps returning an error:

XMLHttpRequest cannot load http://localhost:5500/products. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5000' is therefore not allowed access. 

Research shows that there are/were some issues with Angular and CORS, and that the headers had to be configured to run cross-domain requests. As a result, I added the following to my app.config:

$http.defaults.useXDomain = true;
delete $http.defaults.headers.common['X-Requested-With']; // this isn't needed anymore, but was put here as a just-in-case

Despite having these settings added, I am still getting the error. The Deployd documentation says that it is automatically configured for CORS (Cross-Origin Requests) and will send the appropriate header information as long as the request did not contain invalid custom headers. I'm pretty sure my request does not contain invalid custom headers:

Accept: application/json, text/plain, */*
Cache-Control: max-age=0
Origin: http://localhost:5000
Referer: http://localhost:5000/sportsstore/app.html
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36

My Question: Is there some other configuration I need to put in place in order to have Deployd configured to allow the CORS request to process? The book does not specify any of the special Angular header settings or anything else.

Bic
  • 3,141
  • 18
  • 29

7 Answers7

11

Bic, upgrade your version of deployd to version 0.6.10. This did the trick for me. I was now able to process a get request. It doesn't seem like it's an error with AngularJS code nor Adam Freeman's book.

In the book, he does mention that he includes the deployd program with the source code download on http://www.apress.com/9781430264484. That's version 0.6.9. I'm sure it works fine with it. It'll be easier than to try to find the 0.6.10 version.. which is what I did. Should you want that version, here it is:

https://www.versioneye.com/nodejs/deployd/0.6.10

It's not an installer so you'll have to paste it in your deployd directory, replacing the node_modules.

Serj Sagan
  • 28,927
  • 17
  • 154
  • 183
javaauthority
  • 420
  • 1
  • 4
  • 12
  • I upgraded to 0.6.9, which I got from the book resources as suggested. I think the version on their actual site is 0.6.1, which is evidentally way behind. Ether way, this worked and answer accepted. Thanks. – Bic May 05 '14 at 20:57
  • my dpd version is 0.6.1 and its not working, i have the same CORS issue – naoru Jun 10 '14 at 21:59
  • Nice! This worked for me. BTW, the default install location for `Deployd` is: `C:\Program Files (x86)\Deployd` – Serj Sagan Jul 18 '14 at 00:19
  • 6
    Knew that I had to update from this comment but not how to (without installing and reinstalling). Combining javaauthority, BeDare, and Serj Sagans comments I knew what to do. So for anyone else looking at this you need to do the following: Go to "C:\Program Files (x86)\Deployd", Open a Admin cmd prompt, type "npm update" and everything should work once restarting your Deployd server. – nbonbon Sep 06 '14 at 22:12
  • 1
    "npm update" failed first time I ran it - running again completed successfully and updated to v0.7.0 - CORS now working – Romski Nov 24 '14 at 11:44
  • If you don't want to use the Deployd server from the book, I posted an example below using Java and Wildfly (JBOSS 8.X). The Deployd server is fine for very basic stuff and quick testing, but it simply wasn't meeting my needs, thus why I came up with a Java solution. – javaauthority Feb 10 '15 at 06:27
4

Just run "npm update" in your deployd installation folder and it will make sure you're updated to the latest version 0.6.10. This resolved the issue for me after reading javaauthority's answers (Thanks for that :)).

BeDare
  • 53
  • 5
1

You can place your files (app.html, sportStore.js, ...) under the public folder of your deployd project and use the following URL http://localhost:5500/app.html

Nick
  • 13
  • 4
  • This is a work around that does not solve the CORS issues. If the files were placed in the same folder, then the request would be coming from the same domain. – Bic May 02 '14 at 13:49
  • Yes, sorry should have mentioned that this is a work around and not a solution to the CORS issue. – Nick May 02 '14 at 18:48
1

What I did to solve that issue was starting Chrome with the "--disable-web-security" flag. But first go to Task Manager and close every chrome process you have there.

nothing
  • 76
  • 4
1

While I provided the correct answer and others have improved it, what if you're not using the Deployd web server mentioned in the book? I'm using Wildfly (JBOSS 8.X) and I had to make the CORS issue work for it. I created a simple Java class called CorsFilter. The imports should be fairly easy to find if you're running Wildfly.

Hope this helps other people who are having similar issues with different web servers.

Please note: responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");

Notice the * in the above line? This would allow ANY requests to succeed. This is usually fine for local development work, but tighter security controls should be implemented for Production/Staging environments. For example, you could only accept request from a certain IP address.

import org.jboss.resteasy.annotations.interception.HeaderDecoratorPrecedence;
import org.jboss.resteasy.annotations.interception.ServerInterceptor;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;

/**
 * Class to .
 * User: Java Authority
 * Date: 12/6/2014
 * Time: 12:38 PM
 */
@Provider
@ServerInterceptor
@HeaderDecoratorPrecedence
@WebFilter
public class CorsFilter implements ContainerResponseFilter {

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest r = (HttpServletRequest)request;
        HttpServletResponse s = (HttpServletResponse)response;
        chain.doFilter(request, response);
    }


    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
        responseContext.getHeaders().add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    }
}
javaauthority
  • 420
  • 1
  • 4
  • 12
0

I used fiddler to modify the responses from deployd. This link will show how to add a custom rule to fiddler to add Access-Control-Allow-Origin: * header to all responses. It works great.

http://www.leggetter.co.uk/2010/03/19/using-fiddler-to-help-develop-cross-domain-capable-javascript-web-applications.html

J Cooper
  • 4,828
  • 3
  • 36
  • 39
0

Angular also sends custom headers that DPD rejects, put this in your code for dev to remove these and DPD will work:

delete $http.defaults.headers.common['X-Requested-With'];
Phil Hudson
  • 3,819
  • 8
  • 35
  • 59