server responds with 405 error even with 'Access-Control-Allow-Origin': '*'? - javascript

SO my graphql api is at https://gpbaculio-tributeapp.herokuapp.com/graphql I configured the uploaded, headers like this:
const fetchQuery = (operation, variables) => {
return fetch('/graphql', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify({
query: operation.text,
variables,
}),
}).then(response => {
return response.json()
})
}
I have read from MDN.
For requests without credentials, the server may specify "*" as a
wildcard, thereby allowing any origin to access the resource.
So I am trying to publish the app in codepen, and this is my error:
Failed to load https://gpbaculio-tributeapp.herokuapp.com/graphql:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://s.codepen.io'
Why is it telling me it doesn't pass 'Access-Control-Allow-Origin' headers?
Is there something wrong with my headers config?

You are setting the header in your request (in the client). The Access-Control-Allow-Origin header needs to be set on the server-side, and when you make a request, the response should contain that header.
The reason behind this header is that not every webpage can query every third-party domain. Being able to set this header from the request would defeat that whole point.

Try setting cors options and Access-Control-Allow-Origin headers in server side.
const graphQLServer = express();
const corsOptions = {
origin(origin, callback) {
callback(null, true);
},
credentials: true
};
graphQLServer.use(cors(corsOptions));
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
graphQLServer.use(allowCrossDomain);
This may help you

CORS specification states, that requests for resources are "preflighted" with HTTP OPTIONS request, and reply headers for that OPTIONS must contain header:
Access-Control-Allow-Origin: *
you might check it with curl:
$ curl -I -X OPTIONS https://gpbaculio-tributeapp.herokuapp.com/graphql
HTTP/1.1 405 Method Not Allowed
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Allow: GET, POST
Content-Type: application/json; charset=utf-8
Content-Length: 97
Date: Sat, 23 Sep 2017 11:24:39 GMT
Via: 1.1 vegur
Add OPTION handler with needed header, so your server answers:
$ curl -I -X OPTIONS https://example.localhost/
HTTP/1.1 204 No Content
Server: nginx/1.4.7
Date: Sat, 23 Sep 2017 11:27:51 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range
Content-Type: text/plain; charset=utf-8
Content-Length: 0

The problem is the browser's cross-origin problem.
The Access-Control-Allow-Origin header should be return by the server's response, and the header means the origin domain that can access to the API.
The client's request often take a header Origin, it's value is the current host address, like, www.example.com.
The values of Access-Control-Allow-Origin must contain the value of Origin means that the origin can access this API service. And then the browser will continue the request. If not, the browser will cancel the request.
More infomation, refre to CORS https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Related

React JS - CORS Missing Allow Header when sending POST request

I have some problems with sending a POST request to my REST-API.
The problem is, when I send it from a react application, it shows me this error in the debug console of firefox.
The funny thing is, that it works perfectly fine when sending the request with postman.
This is the code i use to make the request:
let apiURL = API_URL_BASE + "/api/authenticate"
let requestBody = JSON.stringify(
{
"username": this.getEnteredLoginUsername(),
"password": this.getEnteredLoginPassword()
}
);
let headerData = new Headers();
headerData.append('Accept', '*');
headerData.append("Access-Control-Allow", "*");
headerData.append('Content-Type', 'application/json');
headerData.append('Access-Control-Allow-Origin', '*');
headerData.append("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
headerData.append("Access-Control-Allow-Headers", "*");
let requestOptions = {
method: 'POST',
mode: 'cors',
redirect: 'follow',
body: requestBody,
headers: headerData
}
this.setState({loadingData: true});
fetch(apiURL, requestOptions).then( response => {
let responseStatus = response.status;
response.json().then( responseJSON => {
});
});
I hope someone can help me with this.
This is the error shown by firefox console: Image
You do seem to have a correct request header from the client-side, i.e the browser, but your server that is hosting the API must also send a response to the client back indicating that it allows cross-origin requests, Otherwise browser would not proceed ahead with your request. Setting cors headers from the server would depend on what framework you're using for the backend. In fact you need to add those cors header you've added here to the server code.
A sample response header would look like this :
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: * (Note: * means this will allow all domains to request to your server)
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
For express, you can follow this link.
More on CORS here

Javascript Fetch API Cors : Doesen't pass access control check

I am dealing with an external api. I want to post some data so i set a token in the headers to be able to access the api.
I am told that my test origin has been whitelisted http://127.0.0.1:8081/
However i get the following error.
Failed to load
https://external-api.com/api/transactions/ad2d7a69-f723-4798-9fa5-a95a76d65324/document:
Response to preflight request doesn't pass access control check: The
value of the 'Access-Control-Allow-Origin' header in the response must
not be the wildcard '*' when the request's credentials mode is
'include'.
async submitDocument(transationId, token, base64) {
const url = host + "/api/transactions/" + transationId + "/document"
const body = {
"image": base64,
}
let headers = new Headers();
headers.set('Content-type', 'application/json');
headers.set('token', token);
const request = {
method: 'POST',
body: JSON.stringify(body),
mode: 'cors',
headers: headers,
credentials: 'include'
}
const data = await fetch(url, request);
const response = await data.json();
return response;
}
This function call is being made browser side on the following page. http://127.0.0.1:8081/
Response from server
Request URL: https://externalapi.com/api/transactions/f400aaec-3fde-4458-a36e-fe03d550fc00/document
Request Method: OPTIONS
Status Code: 200
Remote Address: 54.194.37.150:443
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Headers: content-type, token
Access-Control-Allow-Methods: GET,POST,PUT,DELETE
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 0
Connection: keep-alive
Content-Length: 0
Date: Fri, 22 Jun 2018 15:29:27 GMT
Server: nginx
Vary: Origin
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Access-Control-Request-Headers: content-type,token
Access-Control-Request-Method: POST
Cache-Control: no-cache
Connection: keep-alive
Host: externalapi.com
Origin: http://127.0.0.1:8081
Pragma: no-cache
Referer: http://127.0.0.1:8081/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
just read the error message carefully! Your domain must not be whitelistet with '*'.
It has to be 'http://127.0.0.1:8081'. You have to ask external-api.com to recheck it.
In your request you have credentials set in a token header and the Origin of your request is:
Origin: http://127.0.0.1:8081
The request in this case will proceed only if the server answers with:
Access-Control-Allow-Origin: http://127.0.0.1:8081
Otherwise the request is blocked by the browser
Check here for more details:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Examples_of_access_control_scenarios
In particular the section "Requests with credentials"

Request nodeJS through a proxy. How to get the response header?

I'm trying to get the response header of a website and get the cookies that i can find inside. There is no problem, it's working when i start the request through a terminal with "node file.js".
But i'm launching the POST request through a local HTML page, so i used browersify for be able to launch a request from a client-side (or at least this is what i understood).
Then i'm using a CORS proxy to get around “No Access-Control-Allow-Origin header” problems. When i start the request from my local HTML page it's working and i can read the body but i'm not able to find the reponse header of the website and get the cookie that i need.
Here how my request looks like:
function connectionInfoConcert(account, psw, next){
console.log("-------------CREATE HEADER-------------\n")
var options = {
method: 'POST',
url: 'https://tranquil-thicket-71867.herokuapp.com/https://www.infoconcert.com/mon-infoconcert/connexion.html',
headers: {
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Language':'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7',
'Cache-Control':'max-age=0',
'Connection':'keep-alive',
'Content-Length':'184',
'Content-Type':'application/x-www-form-urlencoded',
'origin': 'https://www.infoconcert.com',
'referer': 'https://www.infoconcert.com/mon-infoconcert/connexion.html'
},
form: {
origin:'',
username: account,
password: psw
}
};
console.log("-------------END HEADER-------------\n-----------START REQUEST-----------------------")
request(options, function (error, response, body) {
if (!error) {
console.log(response)
console.log(body)
console.log(response.headers['set-cookie'][0]); //obviously 'set-cookie' doesn't exist
}
else {
console.log(error)
console.log(response)
console.log("-------------ERROR------------")
return console.log("Something went wrong")
}
});}
https://www.infoconcert.com/mon-infoconcert/connexion.html is the website where i try to get the cookie
https://tranquil-thicket-71867.herokuapp.com is the CORS proxy that i'm using.
If some of you know how to be able to get the correct header it would be really nice !
Edit 1 :
The problem is when i do my request to "https://www.infoconcert.com/mon-infoconcert/connexion.html" i can find the cookie that i'm looking for in response.headers["set-cookie"].
But because i'm doing the request from a html page it's not working and i'm doing the request to "https://tranquil-thicket-71867.herokuapp.com/https://www.infoconcert.com/mon-infoconcert/connexion.html" but i can't find my cookie in the response.
Here the header of the response i got from "https://tranquil-thicket-71867.herokuapp.com/https://www.infoconcert.com/mon-infoconcert/connexion.html"
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: server,vary,cache-control,content-type,content-encoding,p3p,date,expires,pragma,connection,x-cache-info,x-final-url,access-control-allow-origin
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Thu, 03 May 2018 17:23:49 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
P3p: policyref="/w3c/p3p.xml", CP="NOI DSP COR NID CUR ADM DEV OUR BUS"
Pragma: no-cache
Server: Apache
Transfer-Encoding: chunked
Vary: Accept-Encoding,User-Agent
Via: 1.1 vegur
X-Cache-Info: not cacheable; response specified "Cache-Control: private"
X-Cors-Redirect-1: 302 https://www.infoconcert.com/mon-infoconcert/index.html
X-Cors-Redirect-2: 302 https://www.infoconcert.com/mon-infoconcert/connexion.html
X-Final-Url: https://www.infoconcert.com/mon-infoconcert/connexion.html
X-Request-Url: https://www.infoconcert.com/mon-infoconcert/connexion.html
So i think it's my proxy who doesn't forward the cookie that he gets.
If you need more details just ask.
Thanks you very much for your help

No 'Access-Control-Allow-Origin' header is present on the requested resource even though it is present

I am building an application with Django + Phonegap. When I try to send an Ajax Request using this function:
<script>
$.ajax({
url: "http://192.168.0.101/commerce/product/" + localStorage.getItem("toView"),
type: "GET",
data: {},
success: function (json) {
console.log(json);
}
});
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I get an error saying in the Chrome console:
XMLHttpRequest cannot load http://192.168.0.101/commerce/product/2.
Redirect from 'http://192.168.0.101/commerce/product/2' to
'http://192.168.0.101/commerce/product/2/' has been blocked by CORS
policy: No 'Access-Control-Allow-Origin' header is present on the
requested resource. Origin 'http://192.168.0.101:3000' is therefore
not allowed access.
The problem is in the fact that I am including the requested header. When I open the given URL in chrome and see the server response, I get this.
HTTP/1.0 200 OK
Date: Tue, 16 May 2017 09:42:29 GMT
Server: WSGIServer/0.2 CPython/3.4.3
Content-Type: application/json
Access-Control-Allow-Origin: *
X-Frame-Options: SAMEORIGIN
Access-Control-Allow-Methods: OPTIONS,GET,PUT,POST,DELETE
Access-Control-Allow-Headers: X-Requested-With, Content-Type
Content-Length: 89
I am also including my server code in views.py.
def product(request, prod_id):
#### SOME CODE
response = JsonResponse(response_data)
response['Access-Control-Allow-Origin'] = '*'
response['Access-Control-Allow-Methods'] = 'OPTIONS,GET,PUT,POST,DELETE'
response['Access-Control-Allow-Headers'] = 'X-Requested-With, Content-Type'
return response
Why am I getting this error? Please help. Thanks.
You should add a slash at the end of url in the ajax request:
url: "http://192.168.0.101/commerce/product/" + localStorage.getItem("toView") + '/',
Django expects a trailing slash to be appended to the URL.

AngularJS $http returns status code 0 from failed CORS request

Okay, I've looked all over for this. Basically we're using $http request that ARE cross domain requests. Our server allows the domain and when a request returns 200, everything is OK. However, anytime our server returns an error, 500, 401, whatever, Angular thinks it's a CORS issue.
I debugged the response with Fiddler to verify my server IS returning a 500, yet Angular chokes on it.
Here's the request:
var params = {
url: "fakehost/example",
method: 'GET',
headers: {
"Authorization": "Basic encodedAuthExample"
}
};
$http(params).then(
function (response) { // success
},
function (error) { // error
// error.status is always 0, never includes data error msg
});
Then in the console, I will see this:
XMLHttpRequest cannot load fakehost/example. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'mylocalhost:5750' is therefore not allowed access.
Yet, in fiddler, the true response is:
HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 26 Aug 2014 12:18:17 GMT
Content-Length: 5683
{"errorId":null,"errorMessage":"Index was outside the bounds of the array.","errorDescription":"Stack trace here"}
I'm on AngularJS v1.2.16
I think I found an answer, looks like you will have to inject in your asp.net pipeline the correct CORS headers, as mentioned here.

Categories