17

I would have solved this issue by using jQuery $.ajax function but in this case jQuery is not option. Instead I am going with CORS request. I feel there is something wrong with the webserver that is responding to the request and I am having a hard time figuring out what the issue is.

Here is my code for creating the CORS request

var httpRequest = new XMLHttpRequest();
httpRequest.open('POST', url, true);
httpRequest.setRequestHeader( 'Access-Control-Allow-Origin', '*');
httpRequest.setRequestHeader( 'Content-Type', 'application/json' );
httpRequest.onerror = function(XMLHttpRequest, textStatus, errorThrown) {
  console.log( 'The data failed to load :(' );
  console.log(JSON.stringify(XMLHttpRequest));
};
httpRequest.onload = function() {
  console.log('SUCCESS!');
}

Here is the console.log error:

XMLHttpRequest cannot load http://test.testhost.com/testpage. Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers.

Here are the header information:

> Remote Address:**.**.***.**:80 Request
> URL:http://test.testdomain.com/testpage Request
> Request Method:OPTIONS
> Status Code:200 OK

Request Headers:

OPTIONS /content-network HTTP/1.1
Host: test.testhost.com
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Access-Control-Request-Method: POST
Origin: http://test.testdomain.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
Access-Control-Request-Headers: access-control-allow-origin, content-type
Accept: */*
Referer: http://test.testdomain.com/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

Response Headers:

HTTP/1.1 200 OK
Date: Thu, 14 Aug 2014 20:17:25 GMT
Server: Apache
Last-Modified: Thu, 14 Aug 2014 20:17:25 +0000
Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0
ETag: "1408047445"
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Vary: Accept-Encoding
Content-Encoding: gzip
Access-Control-Allow-Headers: origin, x-requested-with, content-type
Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS
Content-Length: 6117
Connection: close
Content-Type: text/html; charset=utf-8
5
  • 1
    Access-Control-Allow-Origin is a header sent in a server response which indicates that the client is allowed to see the contents of a result; it is not a request header used to demand access to a resource. Do not send Access-Control-Allow-Origin in your request.
    – apsillers
    Commented Aug 14, 2014 at 19:57
  • @apsillers I've added Header set Access-Control-Allow-Origin * to .htaccess, the vhost, and httpd.conf in appache - to no avail, and apache module, headers, IS enabled.
    – CR47
    Commented Aug 14, 2014 at 20:02
  • 1
    The use of non-simple request headers here (Access-Control-Allow-Origin is not a simple header -- and shouldn't be sent by the client -- and application/json is a non-simple value for Content-Type) the browser is sending a preflight OPTIONS request, to check that the server permits these request headers via Access-Control-Allow-Headers.
    – apsillers
    Commented Aug 14, 2014 at 20:07
  • @apsillers - I've edited my question with the new headers, I am getting 200 Response now, but same error from JS in console. This error does not happen with ajax and XDomainRequest, however this is no longer an option.
    – CR47
    Commented Aug 14, 2014 at 20:15
  • @apsillers - Edited them again, They are now correct if they weren't before.
    – CR47
    Commented Aug 14, 2014 at 20:20

5 Answers 5

16

Your server's response allows the request to include three specific non-simple headers:

Access-Control-Allow-Headers:origin, x-requested-with, content-type

but your request has a header not allowed by the server's response:

Access-Control-Request-Headers:access-control-allow-origin, content-type

All non-simple headers sent in a CORS request must be explicitly allowed by the Access-Control-Allow-Headers response header. The unnecessary Access-Control-Allow-Origin header sent in your request is not allowed by the server's CORS response. This is exactly what the "...not allowed by Access-Control-Allow-Headers" error message was trying to tell you.

There is no reason for the request to have this header: it does nothing, because Access-Control-Allow-Origin is a response header, not a request header.

Solution: Remove the setRequestHeader call that adds a Access-Control-Allow-Origin header to your request.

7

Remove:

httpRequest.setRequestHeader( 'Access-Control-Allow-Origin', '*');

... and add:

httpRequest.withCredentials = false;
2
  • @SandeepanNath The user is asking about http, not https. And false is the default setting for withCredentials. When false, cross-site Access-Control requests are made without using credentials such as cookies, authorization headers, or TLS client certificates such as SSL, as in this case. Please don't vote down if you don't understand.
    – Max S.
    Commented Jun 2, 2017 at 0:13
  • Ok but where is my comment? I don't see it anymore Commented Jun 9, 2017 at 6:42
1

In addition to your CORS issue, the server you are trying to access has HTTP basic authentication enabled. You can include credentials in your cross-domain request by specifying the credentials in the URL you pass to the XHR:

url = 'http://username:[email protected]/testpage'
0
0

Enable CORS on backend server or add chrome extensions https://chrome.google.com/webstore/search/CORS?utm_source=chrome-ntp-icon and make ON

0

We see this a lot with OAuth2 integrations. We provide API services to our Customers, and they'll naively try to put their private key into an AJAX call. This is really poor security. And well-coded API Gateways, backends for frontend, and other such proxies, do not allow this. You should get this error.

I will quote @aspillers comment and change a single word: "Access-Control-Allow-Origin is a header sent in a server response which indicates IF the client is allowed to see the contents of a result".

ISSUE: The problem is that a developer is trying to include their private key inside a client-side (browser) JavaScript request. They will get an error, and this is because they are exposing their client secret.

SOLUTION: Have the JavaScript web application talk to a backend service that holds the client secret securely. That backend service can authenticate the web app to the OAuth2 provider, and get an access token. Then the web application can make the AJAX call.

Not the answer you're looking for? Browse other questions tagged or ask your own question.