“Access-Control-Allow-Origin header contains multiple values” error - .htaccess

I'm getting mirriad of errors trying to do an ajax call in a reactjs app using axios. I have an api that lives at a subdomain and making calls from the main domain.
.htaccess:
Header add Access-Control-Allow-Origin: "*"
Header add Access-Control-Allow-Credentials: "true"
Header add Access-Control-Allow-Methods: "GET,HEAD,OPTIONS,POST,PUT"
Header add Access-Control-Allow-Headers: "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"
ajax headers in reactjs (using axios):
var options = {
method: 'GET',
url: 'http://admin.mysite.com/menus/5',
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,HEAD,OPTIONS,POST,PUT',
'Access-Control-Allow-Headers': 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers'
}
}
I've tried making changes to each of these but get different errors. If I have the Header add Access-Control-Allow-Origin: "*" it complains about double origins. If I remove it I I get an error about Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response other changes has responded with Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers in preflight response
I'm using wordpress as a headless CMS and tapping into the restful api to pull the data I need. I have noticed if I removed all of this I can get my data fine but I can't post without fixing the cross domain issues.

If I remove it I I get an error about Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response other changes has responded with Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers in preflight response
Both those error messages are happening because in your frontend JavaScript code you have this:
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,HEAD,OPTIONS,POST,PUT',
'Access-Control-Allow-Headers': 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers'
}
You need to remove that entire headers option from your request code.
The reason is, all the Access-Control-Allow-* headers are response headers that servers must return. The only effect you’ll have by sending them as request headers is to cause exactly the kinds of errors cited in the question.
If the reason you’re adding them is that your .htaccess settings on the server side for the API endpoint you’re sending the request to aren’t making the server send the right response headers, then you need to figure that out and fix that on the server side. Sending additional request headers from the client side isn’t going to fix that problem.
One suggestion you might try for your .htaccess: instead of Header add, use Header set:
Header set Access-Control-Allow-Origin: "*"
Header set Access-Control-Allow-Credentials: "true"
Header set Access-Control-Allow-Methods: "GET,HEAD,OPTIONS,POST,PUT"
Header set Access-Control-Allow-Headers: "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"
Header set tells Apache to overwrite/clobber any existing value that might already be a set for a particular header, whereas Header add tells it to just add a header with the name and value given, without overwriting any header that might already be set with that name.
So Header add can cause multiple headers with the same name to be sent in a response, in which case the browser treats it as a single header with multiple values. You don’t want that.

Related

How to stop CORS error when sending headers?

I want to be connected to a remote API through AJAX via http://localhost:5500. This is my code with a sample URL:
$.ajax({
url: "https://api.website.com/",
headers: { 'x-api-key': 'Sd6g8uieEk8couufkxv9MVp5xdDJBcTSA' },
type: "GET",
withCredentials: false,
success: function(data) { console.log(data) }
});
If I remove the x-api-key part from this code, I have not any issue and receive responses. But, as I add this section to the code, I receive CORS errors:
Access to XMLHttpRequest at
'https://api.website.com/' from origin
'http://localhost:5500' has been blocked by CORS policy: Response to
preflight request doesn't pass access control check: It does not have
HTTP ok status.
I have added different settings in the .htaccess file, but they could not solve the issue:
Header add Access-Control-Allow-Origin "http://localhost:5500"
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Methods "GET, POST, PUT, PATCH, POST, DELETE, OPTIONS"
Header set Access-Control-Allow-Headers: *
I have read many articles, and did many changes on settings, but I could not solve the issue. May you help me please?

Node CORS issues with chrome 85

Since Chrome 85, this error occurs when my front (localhost:8080) send a request to my back (localhost:3000, node app) : 'has been blocked by CORS policy: Cannot parse Access-Control-Allow-Headers response header field in preflight response'
And after playing with my CORS policy in my back, it reveals that when I remove headers with a '/' or a '=', everything works well.
Exemple :
// does not work
res.header(
'Access-Control-Allow-Headers',
'Content-Type, Authorization, Content-Length, application/json, charset=utf-8, X-Requested-With'
)
// works well
res.header(
'Access-Control-Allow-Headers',
'Content-Type, Authorization, Content-Lengths, X-Requested-With'
)
And I do not understand the why.
NB : I read https://www.chromium.org/Home/chromium-security/extension-content-script-fetches, I guess it has something to do with my issue but I still could not manage to fix it.

htaccess Allow Origin Multiple Domains with different Scheme

I need to allow Access-Control-Allow-Origin from the following domains:
http://localhost:8080
app://MyApp
This is my current .htaccess conditions that I need set for both of the above domains:
Header Set Access-Control-Allow-Origin "http://localhost:8080"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Authorization, Accept"
Header Set Access-Control-Expose-Headers "Content-Disposition"
I already read a lot of solutions in SO on this that says to have the server read the Origin header from the client, compare it to the list of domains and then add the values if it matches. However, I am still unable to figure out how will I set my .htaccess file so it includes:
2 different domains that uses different scheme
Also include Access-Control-Allow-Methods, Access-Control-Allow-Headers and Access-Control-Expose-Headers with it.
I don't want to use * unless that is the only option.
Can someone help me rewrite my above .htaccess condition to include the 2 domains please.
This is how I added Multiple Domains with different Scheme along with a check on origin to send back Access-Control-Allow-Origin and other headers with it based on the request origin. I did not want to edit the LiteSpeed config file directly. The following rules in my .htaccess seems to work:
<IfModule mod_headers.c>
SetEnvIf Origin "(http(s)?://localhost:8080)|(app://MyApp)|(app://myapp)$" AccessControlAllowOrigin=$0
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header add Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header add Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Authorization, Accept"
Header add Access-Control-Expose-Headers "Content-Disposition"
Header merge Vary Origin
</IfModule>

CORS using fineuploader

I want to use fineuploader with cross domain.
I get Request header field Cache-Control is not allowed by Access-Control-Allow-Headers in preflight response. error.
My fineuploader config is:
request: {
endpoint: "http://api.polskieszlaki.local/4adm/zdjecia/fileupload",
},
cors: {
expected: true,
},
On my apache server in .htaccess I have
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
I have no firther ideas to make it work.
The message cited in the question indicates you must change your .htaccess to have Cache-Control in the value set for the Access-Control-Allow-Headers response header, and because the Fine Uploader docs indicate it sends the X-Requested-With header, then altogether you need:
Header set Access-Control-Allow-Headers "Cache-Control, Content-Type, Authorization, X-Requested-With"
The MDN docs for the Access-Control-Allow-Headers response header explain:
The Access-Control-Allow-Headers header is used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.

Interacting with expressjs on another server throwing Access-Control-Allow-Headers errors

I am trying to implement Spika web chat ([http://spikaapp.com/][1]) on my Amazon server. I have my website code on one server instance and Spika chat server on another server instance. Spika chat server is up and running. Now when I try to interact with the server on my website I get this error :
XMLHttpRequest cannot load http://example.com:8000/spika/v1/user/list/Boom?_=1468157726669.
Request header field access-token is not allowed by Access-Control-Allow-Headers
in preflight response.
Earlier I had the CORS error I resolved it referring this : http://enable-cors.org/server_expressjs.html
Now I can login but my client but soon after login I get the above error. My current expressjs API handler code for enabling CORS :
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
next();
});
Thanks in advance for the help.
The server (that the POST request is sent to) needs to include the Access-Control-Allow-Headers header (etc) in its response. Putting them in your request from the client has no effect.
This is because it is up to the server to specify that it accepts cross-origin requests (and that it permits the Content-Type request header, and so on) – the client cannot decide for itself that a given server should allow CORS.
When you start playing around with custom request headers you will get a CORS preflight. This is a request that uses the HTTP OPTIONS verb and includes several headers, one of which being Access-Control-Request-Headers listing the headers the client wants to include in the request.
You need to reply to that CORS preflight with the appropriate CORS headers to make this work. One of which is indeed Access-Control-Allow-Headers. That header needs to contain the same values the Access-Control-Request-Headers header contained (or more).
https://fetch.spec.whatwg.org/#http-cors-protocol explains this setup in more detail.
I solved it using https://www.npmjs.com/package/cors. Thanks for all your help guys :)

Resources