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

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);
}
});

Related

Ajax post request not working when i attach headers to request else it works [duplicate]

I would like to add a custom header to an AJAX POST request from jQuery.
I have tried this:
$.ajax({
type: 'POST',
url: url,
headers: {
"My-First-Header":"first value",
"My-Second-Header":"second value"
}
//OR
//beforeSend: function(xhr) {
// xhr.setRequestHeader("My-First-Header", "first value");
// xhr.setRequestHeader("My-Second-Header", "second value");
//}
}).done(function(data) {
alert(data);
});
When I send this request and I watch with FireBug, I see this header:
OPTIONS xxxx/yyyy HTTP/1.1
Host: 127.0.0.1:6666
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Origin: null
Access-Control-Request-Method: POST
Access-Control-Request-Headers: my-first-header,my-second-header
Pragma: no-cache
Cache-Control: no-cache
Why do my custom headers go to Access-Control-Request-Headers:
Access-Control-Request-Headers: my-first-header,my-second-header
I was expecting a header values like this:
My-First-Header: first value
My-Second-Header: second value
Is it possible?
Here is an example how to set a request header in a jQuery Ajax call:
$.ajax({
type: "POST",
beforeSend: function(request) {
request.setRequestHeader("Authority", authorizationToken);
},
url: "entities",
data: "json=" + escape(JSON.stringify(createRequestObject)),
processData: false,
success: function(msg) {
$("#results").append("The result =" + StringifyPretty(msg));
}
});
This code below works for me. I always use only single quotes, and it works fine. I suggest you should use only single quotes or only double quotes, but not mixed up.
$.ajax({
url: 'YourRestEndPoint',
headers: {
'Authorization':'Basic xxxxxxxxxxxxx',
'X-CSRF-TOKEN':'xxxxxxxxxxxxxxxxxxxx',
'Content-Type':'application/json'
},
method: 'POST',
dataType: 'json',
data: YourData,
success: function(data){
console.log('succes: '+data);
}
});
What you saw in Firefox was not the actual request; note that the HTTP method is OPTIONS, not POST. It was actually the 'pre-flight' request that the browser makes to determine whether a cross-domain AJAX request should be allowed:
http://www.w3.org/TR/cors/
The Access-Control-Request-Headers header in the pre-flight request includes the list of headers in the actual request. The server is then expected to report back whether these headers are supported in this context or not, before the browser submits the actual request.
Because you send custom headers so your CORS request is not a simple request, so the browser first sends a preflight OPTIONS request to check that the server allows your request.
If you turn on CORS on the server then your code will work. You can also use JavaScript fetch instead (here)
let url='https://server.test-cors.org/server?enable=true&status=200&methods=POST&headers=My-First-Header,My-Second-Header';
$.ajax({
type: 'POST',
url: url,
headers: {
"My-First-Header":"first value",
"My-Second-Header":"second value"
}
}).done(function(data) {
alert(data[0].request.httpMethod + ' was send - open chrome console> network to see it');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Here is an example configuration which turns on CORS on nginx (nginx.conf file):
location ~ ^/index\.php(/|$) {
...
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
}
Here is an example configuration which turns on CORS on Apache (.htaccess file)
# ------------------------------------------------------------------------------
# | Cross-domain Ajax requests |
# ------------------------------------------------------------------------------
# Enable cross-origin Ajax requests.
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
# http://enable-cors.org/
# <IfModule mod_headers.c>
# Header set Access-Control-Allow-Origin "*"
# </IfModule>
#Header set Access-Control-Allow-Origin "http://example.com:3000"
#Header always set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"
And that is why you can't create a bot with JavaScript, because your options are limited to what the browser allows you to do. You can't just order a browser that follows the CORS policy, which most browsers follow, to send random requests to other origins and allow you to get the response that simply!
Additionally, if you tried to edit some request headers manually, like origin-header from the developers tools that come with the browsers, the browser will refuse your edit and may send a preflight OPTIONS request.
Try to add 'Content-Type':'application/json':
$.ajax({
type: 'POST',
url: url,
headers: {
'Content-Type':'application/json'
}
//OR
//beforeSend: function(xhr) {
// xhr.setRequestHeader("My-First-Header", "first value");
// xhr.setRequestHeader("My-Second-Header", "second value");
//}
}).done(function(data) {
alert(data);
});
From the client side, I can’t solve this problem.
From the Node.js and Express.js side, you can use the cors module to handle it.
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var cors = require('cors');
var port = 3000;
var ip = '127.0.0.1';
app.use('*/myapi',
cors(), // With this row OPTIONS has handled
bodyParser.text({type: 'text/*'}),
function(req, res, next) {
console.log('\n.----------------' + req.method + '------------------------');
console.log('| prot:' + req.protocol);
console.log('| host:' + req.get('host'));
console.log('| URL:' + req.originalUrl);
console.log('| body:', req.body);
//console.log('| req:', req);
console.log('.----------------' + req.method + '------------------------');
next();
});
app.listen(port, ip, function() {
console.log('Listening to port: ' + port);
});
console.log(('dir:' + __dirname));
console.log('The server is up and running at http://' + ip + ':' + port + '/');
Without cors(), these OPTIONS have to appear before POST.
.----------------OPTIONS------------------------
| prot:http
| host:localhost:3000
| url:/myapi
| body: {}
.----------------OPTIONS------------------------
.----------------POST------------------------
| prot:http
| host:localhost:3000
| url:/myapi
| body: <SOAP-ENV:Envelope .. P-ENV:Envelope>
.----------------POST------------------------
The Ajax call:
$.ajax({
type: 'POST',
contentType: "text/xml; charset=utf-8",
//These does not work
//beforeSend: function(request) {
// request.setRequestHeader('Content-Type', 'text/xml; charset=utf-8');
// request.setRequestHeader('Accept', 'application/vnd.realtime247.sct-giro-v1+cms');
// request.setRequestHeader('Access-Control-Allow-Origin', '*');
// request.setRequestHeader('Access-Control-Allow-Methods', 'POST, GET');
// request.setRequestHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type');
//},
//headers: {
// 'Content-Type': 'text/xml; charset=utf-8',
// 'Accept': 'application/vnd.realtime247.sct-giro-v1+cms',
// 'Access-Control-Allow-Origin': '*',
// 'Access-Control-Allow-Methods': 'POST, GET',
// 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type'
//},
url: 'http://localhost:3000/myapi',
data: '<SOAP-ENV:Envelope .. P-ENV:Envelope>',
success: function(data) {
console.log(data.documentElement.innerHTML);
},
error: function(jqXHR, textStatus, err) {
console.log(jqXHR, '\n', textStatus, '\n', err)
}
});
Try to use the rack-cors gem. And add the header field in your Ajax call.

React connecting to Node Cors Preflight Failure

Node Server
var app = express();
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
if ('OPTIONS' == req.method) {
res.send(200);
} else {
next();
}
});
React JS Fetch
function request(url, options) {
return fetch(url, options)
.then(checkStatus)
.then(parseJSON);
}
export function* login() {
const username = yield select(makeSelectUsername());
const password = yield select(makeSelectPassword());
const requestURL = 'http://myurlhere.com:1337/user/login/';
const requestOptions = {
method: 'POST',
mode: 'cors',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(
{username: username,
password: password}
)
}
try {
const result = yield call(request, requestURL, requestOptions);
yield put(loginApiCallSuccess(result));
} catch (err) {
yield put(loginApiCallFailure(err));
}
}
I need help determining what is wrong with my request or server side handling where chrome is cancelling my requests after preflight failure, aka why is my preflight request failing.
I am running the react on localhost and connecting to a remote server with a different url.
From what I can tell the preflight request is failing then chrome is cancelling the request. However when I ran the request locally the login was still hitting the login route on the node side successfully.
When stepping through the code I get a 400 error from the services on the actual call after the preflight call. If I run the call and don't step through I get a
(canceled) in the network tab of dev tools. However the call is successful on the server side each time.
General
Request URL:http://jenkins.murmillosoftware.com:1337/user/register/
Request Method:POST
Status Code:400 Bad Request
Remote Address:52.5.222.29:1337
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept, Origin
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:http://127.0.0.1:3000
Connection:keep-alive
Content-Length:47
Content-Type:application/json; charset=utf-8
Date:Wed, 16 Aug 2017 22:24:48 GMT
ETag:W/"2f-vn6Bxm14Gkpb5HFTCsgU2h3Nq3o"
set-cookie:connect.sid=s%3AjPVtqIoi6zy0QPmhfFkprFObfwj_J-Lw.sPvW3qRc1Vwj4R6qFBtW0oXykF68Qn%2FAwmLCWrg51qc; Path=/; HttpOnly
X-Powered-By:Express
Request Headers
view source
Accept:application/json
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:44
Content-Type:application/json
Host:jenkins.murmillosoftware.com:1337
Origin:http://127.0.0.1:3000
Pragma:no-cache
Referer:http://127.0.0.1:3000/login?
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Request Payload
view source
{username: "fdasfas", password: "asdfasdf"}
password
:
"asdfasdf"
username
:
"fdasfas"
have you ever tried express/cors i recently also had problem with access allow origin then i download express/cors from
npm install cors
then add in your program
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
you can also see other method to use cors in [link]https://github.com/expressjs/cors

How to use the node.js 'request' library with this http request?

I was trying to make a simple request to site. it should get html text, but it gets ' '
NPM module here: github.com/request/request
Code:
var fs = require('fs');
var request = require('request');
var options = {
url:'https://sample.site/phpLoaders/getInventory/getInventory.php',
encoding : 'utf8',
gzip : true,
forever: true,
headers: {
'Host': 'sample.site',
'Connection': 'keep-alive',
'Content-Length': '58',
'Cache-Control': 'max-age=0',
'Accept': '*/*',
'Origin': 'https://csgosell.com',
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': 'https://sample.site/',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4',
'Cookie': 'my-cookies from browser'
},
form: {
stage:'bot',
steamId:76561198284997423,
hasBonus:false,
coins:0
}
};
request.post(options,
function(error, response, body){
console.log(response.statusCode);
if (!error) {
fs.writeFileSync('site.html', body);
}
else{
console.log(error);
}
}
);
Chrome request: https://i.stack.imgur.com/zKQo5.png
Nodejs request:https://i.stack.imgur.com/yH9U3.png
the difference is in headers:
:authority:csgosell.com
:method:POST :path:/phpLoaders/getInventory/getInventory.php :scheme:https
after some googling, I anderstood that it is http2, and tried to put it inow another agent's options, but nothing changed.
var spdy = require('spdy');
var agent = spdy.createAgent({
host: 'sample.site',
port: 443,
spdy: {
ssl: true,
}
}).once('error', function (err) {
this.emit(err);
});
options.agent = agent;
To answer your question i will copy/paste a part of my code that enable you to receive a post request from your frontend application(angularJS) to your backend application (NodeJS), and another function that enable you to do the inverse send a post request from nodeJS to another application (that might consume it):
1) receive a request send from angularJS or whatever inside your nodeJS app
//Import the necessary libraries/declare the necessary objects
var express = require("express");
var myParser = require("body-parser");
var app = express();
// we will need the following imports for the inverse operation
var https = require('https')
var querystring = require('querystring')
// we need these variables for the post request:
var Vorname ;
var Name ;
var e_mail ;
var Strasse ;
app.use(myParser.urlencoded({extended : true}));
// the post request is send from http://localhost:8080/yourpath
app.post("/yourpath", function(request, response ) {
// test the post request
if (!request.body) return res.sendStatus(400);
// fill the variables with the user data
Vorname =request.body.Vorname;
Name =request.body.Name;
e_mail =request.body.e_mail;
Strasse =request.body.Strasse;
response.status(200).send(request.body.title);
});
2) Do the inverse send a POST request from a nodeJS application to another application
function sendPostRequest()
{
// prepare the data that we are going to send to anymotion
var jsonData = querystring.stringify({
"Land": "Land",
"Vorname": "Vorname",
"Name": "Name",
"Strasse": Strasse,
});
var post_options = {
host: 'achref.gassoumi.de',
port: '443',
method: 'POST',
path: '/api/mAPI',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': jsonData.length
}
};
// request object
var post_req = https.request(post_options, function(res) {
var result = '';
res.on('data', function (chunk) {
result += chunk;
console.log(result);
});
res.on('end', function () {
// show the result in the console : the thrown result in response of our post request
console.log(result);
});
res.on('error', function (err) {
// show possible error while receiving the result of our post request
console.log(err);
})
});
post_req.on('error', function (err) {
// show error if the post request is not succeed
console.log(err);
});
// post the data
post_req.write(jsonData);
post_req.end();
// ps : I used a https post request , you could use http if you want but you have to change the imported library and some stuffs in the code
}
So finally , I hope this answer will helps anyone who is looking on how to get a post request in node JS and how to send a Post request from nodeJS application.
For further details about how to receive a post request please read the npm documentation for body-parser library : npm official website documentation

Unable to Post in Angular / Express

I am trying to post using angular but keep getting a 404 error. It looks like the request is not being made. Any ideas why? Thanks for all the help.
var param = $scope.tag;
// client
$http({method: 'Post', url: '/api', headers: {
"Content-Type": "application/json", "Access-Control-Allow-Origin": "*" }, data: {tag: param}})
.then(function(response) {
console.log(response);
});
// server
app.post('/api', function (req, res) {
var tag = req.body.tag;
request("http://food2fork.com/api/search?key=KEY&q=" + tag, function (req, res) {
res.json(response);
});
});
// request headers
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Connection:keep-alive
Content-Length:17
Content-Type:application/json
Host:localhost:3000
// response headers
Connection:keep-alive
Content-Length:22
Content-Type:text/html; charset=utf-8
Date:Sat, 19 Sep 2015 23:22:15 GMT
X-Content-Type-Options:nosniff
X-Powered-By:Express
You should not have to use all that code. Try:
// Client:
var tag = $scope.tag;
$http.post('/api', {tag: tag})
.then(function(response) {
console.log(response);
});
//Server:
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.post('/api', function(req, res) {
var tag = req.body.tag;
res.send(tag);
});
Use method: 'POST' instead of method:'Post'.
The latter is not recognized and a default GET is emitted instead that the POST you expect.
edit: checked the code and what I wrote above is not true
In addition to that...shouldn't be some URL like
/api/tags
???

Access Control Request Headers, is added to header in AJAX request with jQuery

I would like to add a custom header to an AJAX POST request from jQuery.
I have tried this:
$.ajax({
type: 'POST',
url: url,
headers: {
"My-First-Header":"first value",
"My-Second-Header":"second value"
}
//OR
//beforeSend: function(xhr) {
// xhr.setRequestHeader("My-First-Header", "first value");
// xhr.setRequestHeader("My-Second-Header", "second value");
//}
}).done(function(data) {
alert(data);
});
When I send this request and I watch with FireBug, I see this header:
OPTIONS xxxx/yyyy HTTP/1.1
Host: 127.0.0.1:6666
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Origin: null
Access-Control-Request-Method: POST
Access-Control-Request-Headers: my-first-header,my-second-header
Pragma: no-cache
Cache-Control: no-cache
Why do my custom headers go to Access-Control-Request-Headers:
Access-Control-Request-Headers: my-first-header,my-second-header
I was expecting a header values like this:
My-First-Header: first value
My-Second-Header: second value
Is it possible?
Here is an example how to set a request header in a jQuery Ajax call:
$.ajax({
type: "POST",
beforeSend: function(request) {
request.setRequestHeader("Authority", authorizationToken);
},
url: "entities",
data: "json=" + escape(JSON.stringify(createRequestObject)),
processData: false,
success: function(msg) {
$("#results").append("The result =" + StringifyPretty(msg));
}
});
This code below works for me. I always use only single quotes, and it works fine. I suggest you should use only single quotes or only double quotes, but not mixed up.
$.ajax({
url: 'YourRestEndPoint',
headers: {
'Authorization':'Basic xxxxxxxxxxxxx',
'X-CSRF-TOKEN':'xxxxxxxxxxxxxxxxxxxx',
'Content-Type':'application/json'
},
method: 'POST',
dataType: 'json',
data: YourData,
success: function(data){
console.log('succes: '+data);
}
});
What you saw in Firefox was not the actual request; note that the HTTP method is OPTIONS, not POST. It was actually the 'pre-flight' request that the browser makes to determine whether a cross-domain AJAX request should be allowed:
http://www.w3.org/TR/cors/
The Access-Control-Request-Headers header in the pre-flight request includes the list of headers in the actual request. The server is then expected to report back whether these headers are supported in this context or not, before the browser submits the actual request.
Because you send custom headers so your CORS request is not a simple request, so the browser first sends a preflight OPTIONS request to check that the server allows your request.
If you turn on CORS on the server then your code will work. You can also use JavaScript fetch instead (here)
let url='https://server.test-cors.org/server?enable=true&status=200&methods=POST&headers=My-First-Header,My-Second-Header';
$.ajax({
type: 'POST',
url: url,
headers: {
"My-First-Header":"first value",
"My-Second-Header":"second value"
}
}).done(function(data) {
alert(data[0].request.httpMethod + ' was send - open chrome console> network to see it');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Here is an example configuration which turns on CORS on nginx (nginx.conf file):
location ~ ^/index\.php(/|$) {
...
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
}
Here is an example configuration which turns on CORS on Apache (.htaccess file)
# ------------------------------------------------------------------------------
# | Cross-domain Ajax requests |
# ------------------------------------------------------------------------------
# Enable cross-origin Ajax requests.
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
# http://enable-cors.org/
# <IfModule mod_headers.c>
# Header set Access-Control-Allow-Origin "*"
# </IfModule>
#Header set Access-Control-Allow-Origin "http://example.com:3000"
#Header always set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"
And that is why you can't create a bot with JavaScript, because your options are limited to what the browser allows you to do. You can't just order a browser that follows the CORS policy, which most browsers follow, to send random requests to other origins and allow you to get the response that simply!
Additionally, if you tried to edit some request headers manually, like origin-header from the developers tools that come with the browsers, the browser will refuse your edit and may send a preflight OPTIONS request.
Try to add 'Content-Type':'application/json':
$.ajax({
type: 'POST',
url: url,
headers: {
'Content-Type':'application/json'
}
//OR
//beforeSend: function(xhr) {
// xhr.setRequestHeader("My-First-Header", "first value");
// xhr.setRequestHeader("My-Second-Header", "second value");
//}
}).done(function(data) {
alert(data);
});
From the client side, I can’t solve this problem.
From the Node.js and Express.js side, you can use the cors module to handle it.
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var cors = require('cors');
var port = 3000;
var ip = '127.0.0.1';
app.use('*/myapi',
cors(), // With this row OPTIONS has handled
bodyParser.text({type: 'text/*'}),
function(req, res, next) {
console.log('\n.----------------' + req.method + '------------------------');
console.log('| prot:' + req.protocol);
console.log('| host:' + req.get('host'));
console.log('| URL:' + req.originalUrl);
console.log('| body:', req.body);
//console.log('| req:', req);
console.log('.----------------' + req.method + '------------------------');
next();
});
app.listen(port, ip, function() {
console.log('Listening to port: ' + port);
});
console.log(('dir:' + __dirname));
console.log('The server is up and running at http://' + ip + ':' + port + '/');
Without cors(), these OPTIONS have to appear before POST.
.----------------OPTIONS------------------------
| prot:http
| host:localhost:3000
| url:/myapi
| body: {}
.----------------OPTIONS------------------------
.----------------POST------------------------
| prot:http
| host:localhost:3000
| url:/myapi
| body: <SOAP-ENV:Envelope .. P-ENV:Envelope>
.----------------POST------------------------
The Ajax call:
$.ajax({
type: 'POST',
contentType: "text/xml; charset=utf-8",
//These does not work
//beforeSend: function(request) {
// request.setRequestHeader('Content-Type', 'text/xml; charset=utf-8');
// request.setRequestHeader('Accept', 'application/vnd.realtime247.sct-giro-v1+cms');
// request.setRequestHeader('Access-Control-Allow-Origin', '*');
// request.setRequestHeader('Access-Control-Allow-Methods', 'POST, GET');
// request.setRequestHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type');
//},
//headers: {
// 'Content-Type': 'text/xml; charset=utf-8',
// 'Accept': 'application/vnd.realtime247.sct-giro-v1+cms',
// 'Access-Control-Allow-Origin': '*',
// 'Access-Control-Allow-Methods': 'POST, GET',
// 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type'
//},
url: 'http://localhost:3000/myapi',
data: '<SOAP-ENV:Envelope .. P-ENV:Envelope>',
success: function(data) {
console.log(data.documentElement.innerHTML);
},
error: function(jqXHR, textStatus, err) {
console.log(jqXHR, '\n', textStatus, '\n', err)
}
});
Try to use the rack-cors gem. And add the header field in your Ajax call.

Categories

Resources