How to fix this error during client-server
communication? Server sends data in JSON or XML format and client throws below exception.
XMLHttpRequest cannot load https://crunchify.com/api/test. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they’re limited by the same origin policy. Extensions aren’t so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.
Also, if you have below questions then you are at correct location:
- Understanding Cross-Origin Resource Sharing (CORS Filters)
- Can I use Cross-Origin Resource Sharing
- How to Enable Cross-Origin Resource Sharing
- What is Cross-domain Ajax with Cross-Origin Resource Sharing
- What is HTTP access control (CORS)
CORS (Cross Origin Resource Sharing) is a mechanism supported by W3C to enable cross origin requests in web-browsers. CORS requires support from both browser and server to work. This is a Java Jersey Web Server filter implementation of server-side CORS for web containers such as Apache Tomcat and other Embedded Web Servers.
Step-1:
A response can include an Access-Control-Allow-Origin header, with the origin of where the request originated from as the value, to allow access to the resource’s contents. The user agent validates that the value and origin of where the request originated match.
Step-2:
User agents can discover via a preflight request whether a cross-origin resource is prepared to accept requests, using a non-simple method, from a given origin. This is again validated by the user agent.
Step-3:
Server-side applications are enabled to discover that an HTTP request was deemed a cross-origin request by the user agent, through the Origin header. This extension enables server-side applications to enforce limitations (e.g. returning nothing) on the cross-origin requests that they are willing to service.
Now let’s get started with Examples.
Example-1: Java Jersey Web Server
Couple of weeks back I wrote an article on How to Start Embedded HTTP Jersey server during Java Application Startup. This post will cover steps on how to add CORS Filter to the same Jersey Server.
We need to extend ContainerResponseFilter. Interface implemented by container response filters. By default, i.e. if no name binding is applied to the filter implementation class, the filter instance is applied globally to any outgoing response.
In order for this to fix let’s try adding below 4 headers to server response:
- Access-Control-Allow-Origin
- Access-Control-Allow-Methods
- Access-Control-Max-Age
- Access-Control-Allow-Headers
CORS Filter Code:
package com.crunchify.tutorial; /** * * @author Crunchify.com */ import com.sun.jersey.spi.container.ContainerRequest; import com.sun.jersey.spi.container.ContainerResponse; import com.sun.jersey.spi.container.ContainerResponseFilter; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; public class CrunchifyCORSFilter implements ContainerResponseFilter { public ContainerResponse filter(ContainerRequest req, ContainerResponse crunchifyContainerResponse) { ResponseBuilder crunchifyResponseBuilder = Response.fromResponse(crunchifyContainerResponse.getResponse()); // *(allow from all servers) OR https://crunchify.com/ OR http://example.com/ crunchifyResponseBuilder.header("Access-Control-Allow-Origin", "https://crunchify.com/") // As a part of the response to a request, which HTTP methods can be used during the actual request. .header("Access-Control-Allow-Methods", "API, CRUNCHIFYGET, GET, POST, PUT, UPDATE, OPTIONS") // How long the results of a request can be cached in a result cache. .header("Access-Control-Max-Age", "151200") // As part of the response to a request, which HTTP headers can be used during the actual request. .header("Access-Control-Allow-Headers", "x-requested-with,Content-Type"); String crunchifyRequestHeader = req.getHeaderValue("Access-Control-Request-Headers"); if (null != crunchifyRequestHeader && !crunchifyRequestHeader.equals(null)) { crunchifyResponseBuilder.header("Access-Control-Allow-Headers", crunchifyRequestHeader); } crunchifyContainerResponse.setResponse(crunchifyResponseBuilder.build()); return crunchifyContainerResponse; } }
Modification in JerseyEmbeddedHTTPServerCrunchify.java from previous tutorial.
Just add below line in createHttpServer() and restart server.
crunchifyResourceConfig.getContainerResponseFilters().add(CrunchifyCORSFilter.class);
Result:
Here is a Headers details.
Example-2: Apache HTTP Server
To expose the header, you can add the following line inside <Directory>, <Location>, and <Files> sections, or within an .htaccess
file.
<IfModule mod_headers.c> Header set Access-Control-Allow-Origin "*" </IfModule>
Example-3: .NET server can configure this in web.config as below
<system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="your_clientside_websiteurl" /> </customHeaders> <system.webServer>
Example-4: For Jetty (7 and above)
Include the jetty-servlets JAR into you WEB-INF/lib and merge this into your WEB-INF/web.xml
<filter> <filter-name>cross-origin</filter-name> <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class> </filter> <filter-mapping> <filter-name>cross-origin</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Example-5: Apache Tomcat Server (v 7.0.41 +)
<filter> <filter-name>CorsFilter</filter-name> <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> </filter> <filter-mapping> <filter-name>CorsFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Example-6: In PHP
<?php header("Access-Control-Allow-Origin: *"); ?>
Please do let me know if you have any more questions on this. List of all Java Tutorials will be found here.