I have an endpoint https://www..com
When I make a curl call, I have the endpoint as https://www..com?param1=true
I want to do a similar call from Nodejs, I am not sure if param1 should be passed in headers, concatenated to the endpoint or passed in options. What is the right way to do so?
My Node JS looks like this to make calls to my Node Server amd my file looks as follows,
app.post('/thisway', function(req, res){
var ENDPOINT = req.body.endPoint
//(this gets me till https://<url> part of the endpoint string)
var urlToHit = ENDPOINT.concat("?param1=true")
var headers = {
'Authorization': xxxxx,
'Accept': '*/*',
'X-Spark-Service-Instance': xxxxx
}
var options= {
url: urlToHit,
headers: headers,
json: {xxxxxx}
}
request(options, callback);
}
When doing a post it is not necessary to add a query string parameter in the route post. Mostly used for app.get. You can add the details in the JSON string data that you are sending. You can then use the req.body or req.query to get the item. However you can do it this way:
app.post('/thisway/:variable', function(req, res){
Then you retrieve the parameter using req.param.variable
Good EXAMPLE
You can pass it as you have shown in your example in urlToHit. You don't have to pass it in header or options.
var urlToHit = ENDPOINT.concat("?param1=true")
This should complete the request with the needed parameters. Since even when you are doing a curl call, this is the endpoint you hit, it should be the same endpoint here as well.
In your angularjs make a post request to /thisway?variable=true rather than /thisway and in your router you can configure as following:
app.post('/thisway', function(req, res){
var variable = req.query.variable;
if (variable) {
//do something
} else {
//do something
}
});
Related
I'm using angularjs and I'm trying to make a HttpPost call to my web api.
My api method:
[HttpPost]
[Route("authentication/getkey")]
public IHttpActionResult GetKey([FromBody]string password) {
//Do stuff
}
my call:
service.getKey = function (password) {
return $http.post('api/authentication/getkey', JSON.stringify(password))
.then(function(result) {
return result.data;
});
}
Now this works fine, but do I really need to use JSON.stringify? I tried sending it like below, but all of them get password = null. Do I have to use JSON.stringify or am I doing it wrong in my other examples?
//Doesnt work
service.getKey = function (password) {
return $http.post('api/authentication/getkey', password)
.then(function(result) {
return result.data;
});
}
//Doesnt work
service.getKey = function (password) {
return $http.post('api/authentication/getkey', {password})
.then(function(result) {
return result.data;
});
}
If you don't want to use JSON.stringify, the other option will be to send the data as application/x-www-form-urlencoded as pointed in other answer as well. This way you are sending the data as form data. I'm not sure about the syntax of the $http.post Shortcut method but the idea is the same.
service.getKey = function (password) {
$http({
method: 'POST',
url: 'api/authentication/getkey',
data: $.param({ '': password }),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(function(result) {
return result.data;
});
From Microsoft's Web API official documentation about Parameter Binding in ASP.NET Web API:
When a parameter has [FromBody], Web API uses the Content-Type header to select a formatter. In this example, the content type is "application/json" and the request body is a raw JSON string (not a JSON object).
Angular $http service sends Content-Type: application/json as header by default in POST requests, as you can see from the official docs, so Web API is trying to bind your request body using his JsonFormatter. Because of this you have to provide him a well formatted Json string (not a Json Object with a string inside) to correctly bind his raw string parameter.
As a side note, you could also send a request using application/x-www-form-urlencoded as Content-Type header, but then you will have to format your body as form parameters (using something similar to jQuery $.param( .. ))
My REST backend [ based on NodeJS/express/mongojs] is complaining 404 (not found) when Params are attached as part of URL. Backend rest interface is coded as below;
var express = require('express');
var router = express.Router();
router.get('/login', auth.signin); //auth.signin is code to verify user
Above REST service is consumed by AngularJS based frontend through $resource as below;
Definition:
angular.module('myapp').factory('signinmgr', function($resource) {
return $resource("http://localhost:3000/login", {}, {
'get': {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}});
Usage:
signinmgr.get({'username':'myname', 'password':'mypass'}, function(data){
//success
}, function(x){
//failed
});
Problem:
Frontend code above produces a URL to consume REST service where parameters are part of URL i.e. http://localhost:port/login?username=myname&password=mypass [if I use GET method, POST is OK]. I wanted my front end to keep URL as http://localhost:port/login and post any parameters through body as backend is using req.body.paramName to read those. [Actual Solution]
If (1) cannot be done, and my frontend is sending params as part of URL, I needed help as to know how to equip my backend to allow this URL with parameters so that backend doesnt return 404 as the base URL http://localhost:port/login is already there.
PS: for (1), I tried this thread with data:{username:'',password:''} but of no use. Please help if I am missing something very obvious or some concept.
Try the $http service instead:
angular.module('myapp').factor('signinmgr', function($http) {
return {
login: function (username, password) {
$http.post("http://localhost:3000/login", {
username: username,
password: password
}
}
};
});
signinmgr.login('myname', 'mypass').then(function(data){
//success
}, function(x){
//failed
});
Each request that my nodejs/expressjs backend receives has three places for passed attributes;
params{}
query{}
body{}
My problem (1) cannot be fixed in case I want to use GET method since with GET request parameters are visible as part of URL i.e. http://localhost:port/login?username=myname&password=mypass. To send my username/password I had to use POST that sends parameters as part of body{}.
My problem (2) was that I was using GET and mistakenly looking for parameters in body{} of request. Instead, parameters passed as part of URL in GET request are added to query{} of the request.
I need to add a custom header to the $http.get method, I did not understand how to do it.
var hello = _helper.server.http($http, url)
.success(function(response){
//do something
});
How do I add a custom header ('X-user') and a corresponding value (say: "pqrs") ?
I am assuming _helper.server.http is a different function, I think you are making a mistake while passing the header
You have to send the header as a object
var customHeader = {'X-user': 'pqrs'}
to
var hello = _helper.server.http($http, url, customHeader)
and under the function http in _helper.server, you have to add the headers there and then call the http post method,
http: function($http, urlParam, param) {
var request = {
url: urlParam,
headers: param
};
return $http.post(request);
}
It would help if you post more code, this could be the mistake that you are making
You need to use the config :
var config = {headers: {
"X-user" : "pqrs"
}
};
$http.get(url, config).success(function(response){
//Do something
});
https://codeforgeek.com/2014/07/angular-post-request-php/
Hi I was following the above link to give post request from angular js to node js. I received the data posted in below format when i give
console.log(req.body);
{ '{"email":"test#test.com","pass":"password"}': '' }
and when i try to get the value as below, it says undefined.
var email = req.body.email;
console.log(email);
I am unable to get the value of email and pass. Thank you
change the client side header code to headers: { 'Content-Type': 'application/json' }
Your Angular code is sending JSON data, but your Express app is parsing it as URL encoded data.
You probably have something like this in your Express app:
var bodyParser = require('body-parser');
...
app.use(bodyParser.urlencoded());
That last line should be:
app.use(bodyParser.json());
You did not well explain the problem , please next time try to post a bigger part of your code so we could understand what you wanted to do / to say .
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
I hope you enjoyed this and Viel spaß(have fun in german language).
I basically call get requests like so:
var resource = $resource('/api/v1/categories/:id')
resource.get({id: 1}).$promise.then(function(data){
console.log(data)
})
This works fine.. but how do I get the response headers?
You could use the transformResponse action defined here this would allow you add the headers
$resource('/', {}, {
get: {
method: 'GET',
transformResponse: function(data, headers){
response = {}
response.data = data;
response.headers = headers();
return response;
}
}
See a working example here JSFiddle
#Martin's answer works for same domain requests. So I would like to add to his answer that if you are using cross domain requests, you will have to add another header with Access-Control-Expose-Headers: X-Blah, X-Bla along with the Access-Control-Allow-Origin:* header.
where X-Blah and X-Bla are custom headers.
Also you do not need to use transform request to get the headers. You may use this code:
var resource = $resource('/api/v1/categories/:id')
resource.get({id: 1}, function(data, headersFun){
console.log(data, headersFun());
})
See this fiddle.
Hope this helps !!!
Old question, but i think it's worth mentioning for the future reference.
There is 'official' solution for this in angular documentation:
It's worth noting that the success callback for get, query and other
methods gets passed in the response that came from the server as well
as $http header getter function, so one could rewrite the above
example and get access to http headers as:
var User = $resource('/user/:userId', {userId:'#id'});
var users = User.query({}, function(users, responseHeaders){
// ...
console.log(responseHeaders('x-app-pagination-current-page'));
});
(code from docs slightly updated for clarity)
For CORS requests, exposing headers as mentioned in other answers is required.