AlexG
AlexG

Reputation: 1616

Why is my local website unable to access my local REST service?

I have a Spring MVC REST service running locally through Tomcat on port 8080. When I hit the service directly through the browser or fiddler, it works as expected. I also have a local website built with AngularJS. If I place this website in the Tomcat directory and navigate to the website's link served by Tomcat, everything still works fine.

The problem is when I don't place the website in the Tomcat directory. Say I place the website project on my desktop and navigate to a page that is supposed to retrieve data from the local REST service... I can see in fiddler that the request is going through, hitting the service, and the service returns the data... but the website doesn't display it!

Why would it work fine only when both are served by Tomcat?

Link to hit service directly: http://localhost:8080/CPProject/users (returns all the users, in JSON format)

Website (this works): http://localhost:8080/CPWebsite/app/#/users

Website (doesn't work): http://localhost:63342/CPWebsite/app/index.html#/users (63342 is the port used by Webstorm 7.0) or file:///C:/Users/someuser/CPWebsite/app/index.html#/users

My Angular controllers look like this:

cpControllers.controller('UserListCtrl',
    function($scope, $http) {
        $http.get('http://localhost:8080/CP/users')
            .success(function(data) {
                $scope.users = data;
            }
        )
    }
);

I've also created a CORS filter in my Sprint MVC service:

@Component
public class SimpleCORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, HEAD");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}

}

Upvotes: 2

Views: 719

Answers (2)

AlexG
AlexG

Reputation: 1616

Thanks for the answers above. It turns out my CORS filter was fine, but I had forgotten to add it to my application initializer in order for the filter to actually work:

public class WebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) {
        WebApplicationContext rootContext = createRootContext(servletContext);
        configureSpringMvc(servletContext, rootContext);

        FilterRegistration.Dynamic corsFilter = servletContext.addFilter("corsFilter", SimpleCORSFilter.class);
        corsFilter.addMappingForUrlPatterns(null, false, "/*");
    }

See here for more info: http://jpgmr.wordpress.com/2013/12/12/cross-origin-resource-sharing-cors-requests-with-spring-mvc/

Upvotes: 0

user3151168
user3151168

Reputation:

You'll need to add correct configured CORS filter to your app that allows preflight requests. Here's an example configuration:

<filter>
    <filter-name>CORS</filter-name>
    <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>

    <init-param>
        <param-name>cors.allowGenericHttpRequests</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>cors.allowOrigin</param-name>
        <param-value>*</param-value>
    </init-param>

    <init-param>
        <param-name>cors.allowSubdomains</param-name>
        <param-value>false</param-value>
    </init-param>

    <init-param>
        <param-name>cors.supportedMethods</param-name>
        <param-value>GET, HEAD, POST, PUT, DELETE, OPTIONS</param-value>
    </init-param>

    <init-param>
        <param-name>cors.supportedHeaders</param-name>
        <param-value>*</param-value>
    </init-param>

    <init-param>
        <param-name>cors.supportsCredentials</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>cors.maxAge</param-name>
        <param-value>3600</param-value>
    </init-param>

    <init-param>
        <param-name>cors.tagRequests</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>CORS</filter-name>
    <url-pattern>/api/*</url-pattern>
</filter-mapping>

Upvotes: 1

Related Questions