Reputation: 7677
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?login=facebook. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. Error 405
Service:
socialMarkt.factory('loginService', ['$resource', function ($resource) {
var apiAddress = "http://server.apiurl.com:8000/s/login/";
return $resource(apiAddress, {
login: "facebook",
access_token: "@access_token",
facebook_id: "@facebook_id"
}, {
getUser: {
method: 'POST'
}
});
}]);
Controller:
[...]
loginService.getUser(JSON.stringify(fbObj)),
function (data) {
console.log(data);
},
function (result) {
console.error('Error', result.status);
}
[...]
I'm using Chrome. What else can I do in order to fix this problem?
I've even configured the server to accept headers from origin localhost
.
Upvotes: 735
Views: 2506271
Reputation: 51
If some poor soul like me is out there using Django and Nginx with Swagger UI and you've been stuck trying to get an endpoint working with Docker and local https--- make sure you've set your Swagger config to use: 'https://<local-domain.local>'
Upvotes: 1
Reputation:
You are running into CORS issues.
There are several ways to fix or workaround this.
More verbosely, you are trying to access api.serverurl.com from localhost. This is the exact definition of a cross-domain request.
By either turning it off just to get your work done (OK, but poor security for you if you visit other sites and just kicks the can down the road) or you can use a proxy which makes your browser think all requests come from the local host when really you have a local server that then calls the remote server.
So api.serverurl.com might become localhost:8000/api, and your local nginx or other proxy will send to the correct destination.
Now by popular demand, 100% more CORS information—the same great taste!
Bypassing CORS is exactly what is shown for those simply learning the front end. HTTP Example with Promises
Upvotes: 343
Reputation: 121
Check if request is going to correct endpoint. In my Node.js project, I mentioned incorrect endpoint, the request was going to /api/txn/12345
, the endpoint was /api/txn
instead of /api/txn/:txnId
, that led to this error.
Upvotes: 1
Reputation: 113
I made it work, adding the OPTIONS method to Access-Control-Allow-Methods:
Access-Control-Allow-Methods: GET, OPTIONS
But!, again, this works in Chrome and Firefox, but sadly not in Chromium.
Upvotes: 0
Reputation: 694
The "Response to preflight request doesn't pass access control check" is exactly what the problem is:
Before issuing the actual GET request, the browser is checking if the service is correctly configured for CORS. This is done by checking if the service accepts the methods and headers going to be used by the actual request. Therefore, it is not enough to allow the service to be accessed from a different origin, but also the additional requisites must be fulfilled.
Setting headers to
Header always set Access-Control-Allow-Origin: www.example.com
Header always set Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
Header always set Access-Control-Allow-Headers: Content-Type #etc...
will not suffice. You have to add a rewrite rule:
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
A great read Response for preflight does not have HTTP ok status.
Upvotes: 1
Reputation: 14742
My "API Server" is a PHP application, so to solve this problem I found the below solution to work:
Place these lines in file index.php:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
Upvotes: 235
Reputation: 719
For a Python Flask server, you can use the flask-cors plugin to enable cross domain requests.
See: Flask-CORS
Upvotes: 7
Reputation: 3611
In my Apache VirtualHost configuration file, I have added following lines:
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
Upvotes: 9
Reputation: 939
In ASP.NET Core Web API, this issue got fixed by adding "Microsoft.AspNetCore.Cors" (ver 1.1.1) and adding the below changes in 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")]
in the controller.
Upvotes: 63
Reputation: 828
I have faced this problem when the DNS server was set to 8.8.8.8 (Google's). Actually, the problem was in the router. My application tried to connect with the server through Google, not locally (for my particular case).
I have removed 8.8.8.8 and this solved the issue. I know that this issues solved by CORS settings, but maybe someone will have the same trouble as me.
Upvotes: 1
Reputation: 849
If you are using the IIS server by chance, you can set the 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.
Upvotes: 10
Reputation: 11
Something that is very easy to miss...
In Solution Explorer, right-click api-project. In the properties window, set 'Anonymous Authentication' to Enabled!!!
Upvotes: -1
Reputation: 30027
In the manifest.json file, you have to add the permissions for your domain(s).
"permissions": [
"http://example.com/*",
"https://example.com/*",
"http://www.example.com/*",
"https://www.example.com/*"
]
Upvotes: 19
Reputation: 660
The stand-alone 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>
Upvotes: 0
Reputation: 417
For those who are using Lambda Integrated Proxy with API Gateway, you need configure your lambda function as if you are submitting your requests to it directly, meaning the function should set up the response headers properly. (If you are using custom lambda functions, this will be handled by the API Gateway.)
// In your lambda's index.handler():
exports.handler = (event, context, callback) => {
// On success:
callback(null, {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*"
}
}
}
Upvotes: 4
Reputation: 2858
In PHP you can add the headers:
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Expose-Headers: Content-Length, X-JSON");
header("Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: *");
...
Upvotes: 12
Reputation: 2200
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 information 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 documentation here on this link, and you should also check out this Stack Overflow post.
Upvotes: 49
Reputation: 364
I think disabling CORS from Chrome is not good way, because if you are using it in Ionic, certainly in a mobile build the issue will raise again.
So better to fix in your backend.
First of all, in the header, you need to set-
And if the API is behaving as both GET and POST, then also set in your header-
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); exit(0); }
Upvotes: 3
Reputation: 459
I am using AWS SDK for uploads, and after spending some time searching online, I stumbled upon this question. 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 });
Upvotes: 1
Reputation: 142
A very common cause of this error could be that the host API had mapped the request to an HTTP method (e.g., PUT) and the API client is calling the API using a different http method (e.g., POST or GET).
Upvotes: 2
Reputation: 4016
To fix cross-origin-requests issues in a Node.js application:
npm i cors
And simply add the lines below to the app.js file:
let cors = require('cors')
app.use(cors())
Upvotes: 10
Reputation: 1828
Our team occasionally sees this using Vue.js, Axios and a C# Web API. Adding a route attribute on the endpoint you're trying to hit fixes it for us.
[Route("ControllerName/Endpoint")]
[HttpOptions, HttpPost]
public IHttpActionResult Endpoint() { }
Upvotes: 5
Reputation: 2135
Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading of resources
From Cross-Origin Resource Sharing (CORS)
In short - the web server tells you (your browser) which sites you should trust for using that site.
If you are creating a site, and you really don't care who integrates with you. Plow on. Set *
in your ACL.
However, if you are creating a site, and only site X, or even site X, Y and Z should be allowed, you use CORS to instruct the client's browser to only trust these sites to integrate with your site.
Browsers can of course choose to ignore this. Again, CORS protects your client - not you.
CORS allows *
or one site defined. This can limit you, but you can get around this by adding some dynamic configuration to your web server - and help you being specific.
This is an example on how to configure CORS per site is in Apache:
# Save the entire "Origin" header in Apache environment variable "AccessControlAllowOrigin"
# Expand the regex to match your desired "good" sites / sites you trust
SetEnvIfNoCase Origin "^https://(other-good-site\.good|one-more-good.site)$" AccessControlAllowOrigin=$0
# Assuming you server multiple sites, ensure you apply only to this specific site
<If "%{HTTP_HOST} == 'good-api-site.com'">
# Remove headers to ensure that they are explicitly set
Header unset Access-Control-Allow-Origin env=AccessControlAllowOrigin
Header unset Access-Control-Allow-Methods env=AccessControlAllowOrigin
Header unset Access-Control-Allow-Headers env=AccessControlAllowOrigin
Header unset Access-Control-Expose-Headers env=AccessControlAllowOrigin
# Add headers "always" to ensure that they are explicitly set
# The value of the "Access-Control-Allow-Origin" header will be the contents saved in the "AccessControlAllowOrigin" environment variable
Header always set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
# Adapt the below to your use case
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, PUT" env=AccessControlAllowOrigin
Header always set Access-Control-Allow-Headers "X-Requested-With,Authorization" env=AccessControlAllowOrigin
Header always set Access-Control-Expose-Headers "X-Requested-With,Authorization" env=AccessControlAllowOrigin
</If>
Upvotes: 3
Reputation: 31
It's easy to solve this issue just with a few steps easily, without worrying about anything.
Kindly, follow the steps to solve it.
npm install cors
to install via Node.js in a terminalUpvotes: 0
Reputation: 1820
For anyone using API Gateway's HTTP API and the proxy route ANY /{proxy+}
You will need to explicitly define your route methods in order for CORS to work.
I wish this was more explicit in the AWS documentation for configuring CORS for an HTTP API
I was on a two-hour call with AWS support and they looped in one of their senior HTTP API developers, who made this recommendation.
Upvotes: 4
Reputation: 7059
Using the CORS option in the API gateway, I used the following settings shown above.
Also, note, that your function must return a HTTP status 200 in response to an OPTIONS request, or else CORS will also fail.
Upvotes: 1
Reputation: 6809
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
Upvotes: 16