CORS PUT: Not found with jQuery.ajax - javascript

I want to send some raw data to a subdomain of mine:
$.ajax({
url: "http://accounts.example.com:3000/me",
type: "PUT",
data: { wabo: "chabo" },
dataType: "json",
xhrFields: {
withCredentials: true
}
});
The browser now sends two requests:
OPTIONS to accounts.example.com:3000/me to check if CORS headers are valid
PUT to send data
The first one fails with HTTP 404 Not Found.
The CORS repsonse header looks valid:
HTTP/1.1 404 Not Found
X-Powered-By: Express
Access-Control-Allow-Origin: http://node.example.com:3000
Access-Control-Allow-Methods: HEAD, GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-Requested-With, Origin, Accept
Access-Control-Allow-Credentials: true
Content-Type: text/plain
Set-Cookie: connect.sid=s%3Aru8njoU2ZAnoKL2W2w%2B0BHF7.%2Fe%2FQI5f6NKRWQvWlcYEkMG7HHSxxj0haFDBUID2g45A; Domain=.example.com; Path=/
Date: Sun, 04 Nov 2012 11:31:22 GMT
Connection: keep-alive
Transfer-Encoding: chunked
In app.js of my node environment I have:
app.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://node.example.com:3000');
res.header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With, Origin, Accept');
res.header('Access-Control-Allow-Credentials', 'true');
next();
});
and
var me = require('./me');
app.get('/me', loadUser, me.show);
app.put('/me', loadUser, me.update);
GETting data from the subdomain is no problem only sending
Any idea what I have forgotten?
Regards, bodo

Try this instead:
app.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://node.example.com:3000');
res.header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With, Origin, Accept');
res.header('Access-Control-Allow-Credentials', 'true');
if( req.method.toLowerCase() === "options" ) {
res.send( 200 );
}
else {
next();
}
});

Related

Why Set-Cookie is not stored?

I have following HTTP response:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, authorization, content-type, origin, x-requested-with, user-agent, access-control-allow-origin, crossdomain, access-control-allow-credentials, x-requested-with
Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE, PATCH
Access-Control-Allow-Origin: https://speechifai-dashboard-fe.herokuapp.com
Access-Control-Max-Age: 600
Connection: keep-alive
Content-Length: 35
Content-Type: application/json; charset=utf-8
Date: Fri, 25 Feb 2022 05:52:17 GMT
Server: Cowboy
Set-Cookie: sessionIdSp=+5BtM+x+ZZ262Vs362qgUUmJE8PXd12G+AwMSdH14JQ=; Path=/; Secure; HttpOnly; SameSite=Lax
Link is here, you can try: https://speechifai-dashboard-fe.herokuapp.com/createPost
So frontend connect to backend, backend sends cookie, but I can not see under Cookies, why? What do I miss?
I have a Vapor backend:
It has following setting, what is wrong?
app.middleware.use(CORSMiddleware(configuration: .init(
allowedOrigin: .originBased,//.originBased,
allowedMethods: [.GET, .POST, .PUT, .OPTIONS, .DELETE, .PATCH],
allowedHeaders: [.accept, .authorization, .contentType, .origin, .xRequestedWith, .userAgent, .accessControlAllowOrigin, .init("crossDomain"), .accessControlAllowCredentials, .xRequestedWith],
allowCredentials: true
)), at: .beginning)
// Change the cookie name to "foo".
app.sessions.configuration.cookieName = cookieName
// Configures cookie value creation.
app.sessions.configuration.cookieFactory = { sessionID in
print("sessionID.string: \(sessionID.string)")
return .init(string: sessionID.string, isSecure: true, isHTTPOnly: true)
}
Calling here backend from React frontend:
axios({
method: "post",
url: "registerEmail",
data: {},
headers: {
"Content-Type": "application/json",
crossDomain: true,
},
})
.then((res) => {
dispatch(setGetUser(res.data));
})
.catch((err) => console.error(err));

javascript fetch never reaches the POST request on nodejs server

I am trying to post some data to my nodejs server using fetch api but it seems the fetch request never reaches my server..
Fetch code
const resp = await fetch("http://localhost:5000/api/students/", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: `{
"name": "Ahmed",
"seat": 4
}`
});
console.log(resp);
const json = await resp.json();
return json;
nodeJS post body
route.post("/", CORS, async (req, res) => {
console.log('abc', req.body);
const {
error
} = validateStudent(req.body);
if (error) return res.status(400).send(error.details[0].message);
const result = await addStudent(req.body);
if (!result) return res.status(400).send("Student cannot be added");
res.status(200).send(result);
});
code of CORS middleware
console.log('avcx');
res.header("Access-Control-Allow-Origin", "*").header(
"Access-Control-Allow-Credentials", true);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
console.log('acvced');
next();
As you can see I've done some logs on my server but nothing shows up... BTW eveything is working fine with get request..
sending the same request with postman works fine.
I don't know why I'm getting this error I tackled this error for GET requests by creating a middleware 'CORS' but I'm still getting this error for POST request:-
Thanks in advance :)
I solved this problem. I wasn't handling the incoming requests correctly because I didn't know that fetch sends a preflight request with an OPTION method before sending the actual POST request. So I solved it by adding this line in my index file above every other request which will be executed every time a request (with any method) is made.
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*").header(
"Access-Control-Allow-Credentials", true);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", " GET, POST, PUT, PATCH, POST, DELETE, OPTIONS");
next();
});

CORS request 405 status code

Hello everyone please help me about my CORS problem
Im creating an API request from another domain my code below with an error,
var headers = {
host: host,
path: url + instance + '?action=reset',
method: 'POST'
};
var request = https.request(headers, function (response) {
logger('OCICompute', 'reset', 'INSTANCE', 'Got response from OPCAPI:' + response.statusCode);
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Methods", "OPTIONS, TRACE, GET, HEAD, POST, PUT");
res.header("Access-Control-Expose-Headers", "Origin, Content-Type, Authorization, Accept, X-Requested-With");
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Headers", "Origin, Content-Type, Authorization, Accept, X-Requested-With");
if (response.statusCode === 200) {
response.on('data', function (body) {
var data = JSON.parse(body);
res.json(data);
});
} else {
logger('OCICompute', 'reset', 'ERROR', 'stop fail');
res.json({'result': 'Fail'});
}
});
code above is on my module
and I have option in my main.
app.opts('/\.*/', function(req, res, next){
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Methods", "OPTIONS, TRACE, GET, HEAD, POST, PUT");
res.header("Access-Control-Expose-Headers", "Origin, Content-Type, Authorization, Accept, X-Requested-With");
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Headers", "Origin, Content-Type, Authorization, Accept, X-Requested-With");
res.send(200);
});
When I access this rest im getting this
405 error method not accepted and only got this
Host: api Url
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: */*
Accept-Language: ja,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
Referer: http://localhost:3000/?root=compute
Authorization: Bearer Token
Origin: http://localhost:3000
Connection: keep-alive
Allow: OPTIONS
Connection: keep-alive
Content-Length: 58
Content-Type: application/json
Date: Tue, 24 Apr 2018 02:05:47 GMT
Server: LBAAS
Strict-Transport-Security: max-age=31536000; includeSubdomains;
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
I have another code which do exactly what I expected, the only difference is im using GET method. Above with error is POST.
var headers = {
host: host,
path: url + instance + '?action=reset',
method: **'GET'**
};
And here is the result
>
Host: api Url User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0)
> Gecko/20100101 Firefox/52.0 Accept: */* Accept-Language:
> ja,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate, br Referer:
> http://localhost:3000/?root=compute Authorization: Bearer Token
> Origin: http://localhost:3000 Connection: keep-alive
>
> Access-Control-Allow-Credentials: true Access-Control-Allow-Headers:
> Content-Type, Authorization, Accept, X-Requested-With
> Access-Control-Allow-Methods: OPTIONS, TRACE, GET, HEAD, POST, PUT
> Access-Control-Allow-Origin: http://localhost:3000
> Access-Control-Expose-Headers: Content-Type, Authorization, Accept,
> X-Requested-With Connection: keep-alive Content-Length: 2556
> Content-Type: application/json Date: Tue, 24 Apr 2018 02:05:57 GMT
> Server: LBAAS Strict-Transport-Security: max-age=31536000;
> includeSubdomains; X-Content-Type-Options: nosniff X-XSS-Protection:
> 1; mode=block
Here is my code on client side
self.stopButtonClick = function (event) {
console.log("停止ボタンが押されました");
var headers = {"Authorization": 'Bearer ' + self.ociComputeToken._latestValue};
$.ajax({
url: url,
type: "GET",
async: true,
headers: headers
}).done(function (data, textStatus, jqXHR) {
if (data.result !== 'Fail') {
self.compartmentHandler(self.compartmentId());
} else {
self.stopButtonClick(event);
}
}).fail(function (jqXHR, textStatus, errorThrown) {
console.log('サービスエラー');
self.stopButtonClick(event);
});
};
I just solve this one, and the problem is the url that im accessing is not correct, But then I got another error which is 502 bad gateway, GET is working fine, but what should I do when POST method is use?

fetch OPTIONS return HTTP 401 while Curl Command succeeds

This is what my fetch code looks like
let getSummary = (year, month) => {
let url = baseUrl + "/rest/monthlySummaries/" +
localStorage.getItem("paUserId") + "/" + year + "/" + month;
let authHeaders = {
"Content-Type": "application/json",
"Accept": "application/json",
"Bearer": localStorage.getItem("paToken")
};
console.log("summary url:", url, ",headers:", authHeaders);
return fetch(url, {
method: "GET",
headers: authHeaders
});
};
Since this is GET request, browsers make preflight reqeusts using HTTP OPTIONS to make sure that they make indeed make HTTP GET requests. I log what call is made, I see
summary url: https://api.myapp.com/rest/monthlySummaries/userId/2017/4 ,headers: Object {Content-Type: "application/json", Accept: "application/json", Bearer: "41afa8432aaa411e48b6c1c637c77cb3:userId:84000000"}Accept: "application/json"Bearer: "41afa8432aaa411e48b6c1c637c77cb3:userId:84000000"Content-Type: "application/json"__proto__: Object
2VM50885:1 OPTIONS https://api.myapp.com/rest/monthlySummaries/cca6b151-cab4-4de2-81db-9a739a62ae88/2017/4 401 (Unauthorized)
While, when I do similar thing on curl, everything works
curl -v -X OPTIONS -H"BEARER:e3310afc4dcd68d80d56a83bddfd4a09:userId:564000000" "https://api.myapp.com/rest/monthlySummaries/userId/2017/4"
* Trying 52.23.254.96...
* Connected to api.myapp.com (52.23.254.96) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: DigiCert SHA2 High Assurance Server CA
* Server certificate: DigiCert High Assurance EV Root CA
> OPTIONS /rest/monthlySummaries/userId/2017/4 HTTP/1.1
> Host: api.myapp.com
> User-Agent: curl/7.43.0
> Accept: */*
> BEARER:e3310afc4dcd68d80d56a83bddfd4a09:userId:564000000
>
< HTTP/1.1 200 OK
< Date: Mon, 29 May 2017 23:21:11 GMT
< Server: WildFly/8
< X-Powered-By: Undertow/1
< Access-Control-Allow-Headers: origin, content-type, accept, authorization
< Allow: HEAD, GET, OPTIONS
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
< Content-Type: text/plain
< Content-Length: 18
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD
< Access-Control-Max-Age: 1209600
< Vary: Accept-Encoding
<
* Connection #0 to host api.myapp.com left intact
Why the behavior is so different? What am I missing in fetch?
UPDATE
My server enables CORS support
#Provider
public class CORSFilter implements ContainerResponseFilter {
#Override
public void filter(ContainerRequestContext containerRequestContext,
ContainerResponseContext containerResponseContext) throws IOException {
containerResponseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
containerResponseContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
containerResponseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
containerResponseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
containerResponseContext.getHeaders().add("Access-Control-Max-Age", "1209600");
}
}
This can be seen in the response as well
See where you have configured
.add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
You haven't allowed the Bearer header, nor is it the correct way to pass a JWT.
You probably meant
"Authorization": `Bearer ${localStorage.getItem("paToken")}`
Sending Bearer when it isn't in the allowed headers list will fail the pre-flight validation.

Access-Control-Allow-Origin and Angular.js $http

Whenever I make a webapp and I get a CORS problem, I start making coffee. After screwing with it for a while I manage to get it working but this time it's not and I need help.
Here is the client side code:
$http({method: 'GET', url: 'http://localhost:3000/api/symbol/junk',
headers:{
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, X-Requested-With',
'X-Random-Shit':'123123123'
}})
.success(function(d){ console.log( "yay" ); })
.error(function(d){ console.log( "nope" ); });
The server side is a regular node.js with an express app. I have an extention called cors and it's being used with express this way:
var app = express();
app.configure(function(){
app.use(express.bodyParser());
app.use(app.router);
app.use(cors({origin:"*"}));
});
app.listen(3000);
app.get('/', function(req, res){
res.end("ok");
});
If I do
curl -v -H "Origin: https://github.com" http://localhost:3000/
It gets back with:
* Adding handle: conn: 0x7ff991800000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7ff991800000) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 3000 (#0)
* Trying ::1...
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:3000
> Accept: */*
> Origin: https://github.com
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Date: Tue, 24 Dec 2013 03:23:40 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
* Connection #0 to host localhost left intact
ok
If I run the client side code, it brigs up this error:
OPTIONS http://localhost:3000/api/symbol/junk No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. angular.js:7889
XMLHttpRequest cannot load http://localhost:3000/api/symbol/junk. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. localhost/:1
nope
Checking Chromes headers:
Request URL:http://localhost:3000/api/symbol/junk
Request Method:OPTIONS
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,es;q=0.6,pt;q=0.4
Access-Control-Request-Headers:access-control-allow-origin, accept, access-control-allow-methods, access-control-allow-headers, x-random-shit
Access-Control-Request-Method:GET
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost:3000
Origin:http://localhost:8000
Referer:http://localhost:8000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Response Headersview source
Allow:GET
Connection:keep-alive
Content-Length:3
Content-Type:text/html; charset=utf-8
Date:Tue, 24 Dec 2013 03:27:45 GMT
X-Powered-By:Express
Checking the request headers I see that my test string X-Random-Shit is present in the "Access-Control-Request-Headers" but it's value is not there. Also, in my head I was expecting to see one line for each one of the headers I am setting, not a blob.
UPDATES ---
I changed my frontend to jQuery instead of Angular and made my backend like this:
var app = express();
app.configure(function(){
app.use(express.bodyParser());
app.use(app.router);
});
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'OPTIONS,GET,POST,PUT,DELETE');
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
if ('OPTIONS' == req.method){
return res.send(200);
}
next();
});
app.get('/', function(req, res){
res.end("ok");
});
Now it works with GET but does not with anything else (PUT, POST..).
I'll see if any of you comes up with a solution. In the mean time in throwing the RESTful concept out the window and making everything with GETs.
I'm new to AngularJS and I came across this CORS problem, almost lost my mind! Luckily i found a way to fix this. So here it goes....
My problem was, when I use AngularJS $resource in sending API requests I'm getting this error message XMLHttpRequest cannot load http://website.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. Yup, I already added callback="JSON_CALLBACK" and it didn't work.
What I did to fix it the problem, instead of using GET method or resorting to $http.get, I've used JSONP. Just replace GET method with JSONP and change the api response format to JSONP as well.
myApp.factory('myFactory', ['$resource', function($resource) {
return $resource( 'http://website.com/api/:apiMethod',
{ callback: "JSON_CALLBACK", format:'jsonp' },
{
method1: {
method: 'JSONP',
params: {
apiMethod: 'hello world'
}
},
method2: {
method: 'JSONP',
params: {
apiMethod: 'hey ho!'
}
}
} );
}]);
I hope someone find this helpful. :)
I've had success with express and editing the res.header. Mine matches yours pretty closely but I have a different Allow-Headers as noted below:
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
I'm also using Angular and Node/Express, but I don't have the headers called out in the Angular code only the node/express
Writing this middleware might help !
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
for details visit http://enable-cors.org/server_expressjs.html
Adding below to server.js resolved mine
server.post('/your-rest-endpt/*', function(req,res){
console.log('');
console.log('req.url: '+req.url);
console.log('req.headers: ');
console.dir(req.headers);
console.log('req.body: ');
console.dir(req.body);
var options = {
host: 'restAPI-IP' + ':' + '8080'
, protocol: 'http'
, pathname: 'your-rest-endpt/'
};
console.log('options: ');
console.dir(options);
var reqUrl = url.format(options);
console.log("Forward URL: "+reqUrl);
var parsedUrl = url.parse(req.url, true);
console.log('parsedUrl: ');
console.dir(parsedUrl);
var queryParams = parsedUrl.query;
var path = parsedUrl.path;
var substr = path.substring(path.lastIndexOf("rest/"));
console.log('substr: ');
console.dir(substr);
reqUrl += substr;
console.log("Final Forward URL: "+reqUrl);
var newHeaders = {
};
//Deep-copy it, clone it, but not point to me in shallow way...
for (var headerKey in req.headers) {
newHeaders[headerKey] = req.headers[headerKey];
};
var newBody = (req.body == null || req.body == undefined ? {} : req.body);
if (newHeaders['Content-type'] == null
|| newHeaders['Content-type'] == undefined) {
newHeaders['Content-type'] = 'application/json';
newBody = JSON.stringify(newBody);
}
var requestOptions = {
headers: {
'Content-type': 'application/json'
}
,body: newBody
,method: 'POST'
};
console.log("server.js : routes to URL : "+ reqUrl);
request(reqUrl, requestOptions, function(error, response, body){
if(error) {
console.log('The error from Tomcat is --> ' + error.toString());
console.dir(error);
//return false;
}
if (response.statusCode != null
&& response.statusCode != undefined
&& response.headers != null
&& response.headers != undefined) {
res.writeHead(response.statusCode, response.headers);
} else {
//404 Not Found
res.writeHead(404);
}
if (body != null
&& body != undefined) {
res.write(body);
}
res.end();
});
});
#Swapnil Niwane
I was able to solve this issue by calling an ajax request and formatting the data to 'jsonp'.
$.ajax({
method: 'GET',
url: url,
defaultHeaders: {
'Content-Type': 'application/json',
"Access-Control-Allow-Origin": "*",
'Accept': 'application/json'
},
dataType: 'jsonp',
success: function (response) {
console.log("success ");
console.log(response);
},
error: function (xhr) {
console.log("error ");
console.log(xhr);
}
});
I have found a way to use JSONP method in $http directly and with support of params in the config object:
params = {
'a': b,
'callback': 'JSON_CALLBACK'
};
$http({
url: url,
method: 'JSONP',
params: params
})
Try with this:
$.ajax({
type: 'POST',
url: URL,
defaultHeaders: {
'Content-Type': 'application/json',
"Access-Control-Allow-Origin": "*",
'Accept': 'application/json'
},
data: obj,
dataType: 'json',
success: function (response) {
// BindTableData();
console.log("success ");
alert(response);
},
error: function (xhr) {
console.log("error ");
console.log(xhr);
}
});

Categories

Resources