I\'m getting this error using ngResource to call a REST API on Amazon Web Services:
XMLHttpRequest cannot load http://server.apiurl.com:8000/s/login
There are some caveats when it comes to CORS. First, it does not allow wildcards *
but don't hold me on this one I've read it somewhere and I can't find the article now.
If you are making requests from a different domain you need to add the allow origin headers.
Access-Control-Allow-Origin: www.other.com
If you are making requests that affect server resources like POST/PUT/PATCH, and if the mime type is different than the following application/x-www-form-urlencoded
, multipart/form-data
, or text/plain
the browser will automatically make a pre-flight OPTIONS request to check with the server if it would allow it.
So your API/server needs to handle these OPTIONS requests accordingly, you need to respond with the appropriate access control headers
and the http response status code needs to be 200
.
The headers should be something like this, adjust them for your needs:
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400
The max-age header is important, in my case, it wouldn't work without it, I guess the browser needs the info for how long the "access rights" are valid.
In addition, if you are making e.g. a POST
request with application/json
mime from a different domain you also need to add the previously mentioned allow origin header, so it would look like this:
Access-Control-Allow-Origin: www.other.com
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400
When the pre-flight succeeds and gets all the needed info your actual request will be made.
Generally speaking, whatever Access-Control
headers are requested in the initial or pre-flight request, should be given in the response in order for it to work.
There is a good example in the MDN docs here on this link, and you should also check out this SO post
If you are using IIS server by chance. you can set below headers in the HTTP request headers option.
Access-Control-Allow-Origin:*
Access-Control-Allow-Methods: 'HEAD, GET, POST, PUT, PATCH, DELETE'
Access-Control-Allow-Headers: 'Origin, Content-Type, X-Auth-Token';
with this all post, get etc., will work fine.
In AspNetCore web api, this issue got fixed by adding "Microsoft.AspNetCore.Cors" (ver 1.1.1) and adding the below changes on Startup.cs.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("AllowAllHeaders",
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
.
.
.
}
and
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// Shows UseCors with named policy.
app.UseCors("AllowAllHeaders");
.
.
.
}
and putting [EnableCors("AllowAllHeaders")]
on the controller.
JavaScript XMLHttpRequest and Fetch follow the same-origin policy. So, a web application using XMLHttpRequest or Fetch could only make HTTP requests to its own domain.
Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
You have to send the Access-Control-Allow-Origin: * HTTP header from your server side.
If you are using Apache as your HTTP server then you can add it to your Apache configuration file like this:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
Mod_headers is enabled by default in Apache, however, you may want to ensure it's enabled by running:
a2enmod headers
The standalone distributions of GeoServer include the Jetty application server. Enable Cross-Origin Resource Sharing (CORS) to allow JavaScript applications outside of your own domain to use GeoServer.
Uncomment the following <filter>
and <filter-mapping>
from webapps/geoserver/WEB-INF/web.xml:
<web-app>
<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>
</web-app>
I am using AWS sdk for uploads, after spending some time searching online i stumbled upon this thread. thanks to @lsimoneau 45581857 it turns out the exact same thing was happening. I simply pointed my request Url to the region on my bucket by attaching the region option and it worked.
const s3 = new AWS.S3({
accessKeyId: config.awsAccessKeyID,
secretAccessKey: config.awsSecretAccessKey,
region: 'eu-west-2' // add region here });