Post request from Backbone client to NodeJS service - javascript

Somehow I am not able to send data from Backbone model to NodeJS service.
Backbone Model
var Money = Backbone.Model.extend({
url: 'http://localhost:3000/sendCoins',
defaults: {
fromAddress: "",
toAddress: "",
amount: ""
},
transferMoney: function(req, resp) {
//get field values
console.log(req.fromAddress); //prints fine
this.save();
}
});
var transferMoney = new Money();
Node JS service
var app = express();
app.listen(3000);
app.use(express.json());
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
app.post('/sendCoins', function(req, res) {
console.log(req.body.toAddress);
console.log(JSON.stringify(req.body));
console.log(req.body.amount);
});
When I post the request from backbone view console.log(JSON.stringify(req.body)); prints {"fromAddress":"","toAddress":"","amount":""}.

As mentionned by M Omary, you need to use the body parser in order to have access to req.body. Add the following code above app.post to see if it works:
app.use(express.bodyParser());

Related

How to use rest api in client side?

Hello today I have simple code Nodejs express that work as rest api. It work when i use postman to send request as get method like code below. But i try use it in client. it doesn't work . So can you help find mistake,please?
// simple rest api
router.get('/getuser', function(req, res, next) {
var connection = getcon();
res.setHeader('Content-Type', 'application/json');
connection.query('SELECT username,password from tbuser', function (error, results, fields) {
if (error) throw error;
console.log('Object : ', JSON.stringify(results));
res.send(JSON.stringify(results));
});
connection.end();
});
// client code
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http.get("http://localhost:3000/users/getuser")
.then(function(response) {
$scope.myWelcome = response.data;
});
});
</script>
It seems like you supply incorrect URL in the client script.
Based on your nodejs code URL must be http://localhost:3000/getuser
UPDATE
You end your connection before you send results. Just move connection.end() inside your callback
if (error) throw error;
console.log('Object : ', JSON.stringify(results));
res.send(JSON.stringify(results));
connection.end();
});
You need to enable Cross-Origin Resource Sharing, a mechanism gives web servers cross-domain access controls, which enable secure cross-domain data transfers. Add this before your router:
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-type');
res.setHeader('Access-Control-Allow-Headers', 'X-Signature');
res.setHeader('Access-Control-Allow-Headers', 'X-Key');
next();
}
);

Cannot GET / DELETE Express.js

I have this script with which I'm trying to POST, GET and DELETE some stuff.
When I try POST or GET, the right messages are logged, but when I try DELETE, I get the following error:
Cannot GET /del_user
The URL I'm using is http://127.0.0.1:8081/del_user
What can be wrong in here?
var express = require('express');
var app = express();
// This responds with "Hello World" on the homepage
app.get('/', function (req, res) {
console.log("Got a GET request for the homepage");
res.send('Hello GET');
})
// This responds a POST request for the homepage
app.post('/', function (req, res) {
console.log("Got a POST request for the homepage");
res.send('Hello POST');
})
// This responds a DELETE request for the /del_user page.
app.delete('/del_user', function (req, res) {
console.log("Got a DELETE request for /del_user");
res.send('Hello DELETE');
})
// This responds a GET request for the /list_user page.
app.get('/list_user', function (req, res) {
console.log("Got a GET request for /list_user");
res.send('Page Listing');
})
// This responds a GET request for abcd, abxcd, ab123cd, and so on
app.get('/ab*cd', function(req, res) {
console.log("Got a GET request for /ab*cd");
res.send('Page Pattern Match');
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
I solved it by changing the app.delete to app.get and then placing the required remove statement inside the app.get. Something like this :-
app.get('/delete/:userId', (req, res) => {
Users.remove({ _id: req.params.userId }, (error, posts) => {
if (error) {
console.warn(error);
}
else {
data = posts
res.render("delete", {"data": data})
}
});
});
In your code you're binding the /del_user URL to the HTTP DELETE method.
So all you need to do is specify the DELETE method in your application or in Postman.
If you're not using it, it's an App in Google Chrome and you might want to download it, it makes your life a LOT easier ;)
Also, since the HTTP method is already declared to be DELETE, there is no need to specify it in the URL.
This is part of the RESTful working.
If you are using AJAX to try your code, you need to specify the method, which is delete.
$.ajax({
url: "http://127.0.0.1:8081/del_user",
type: "DELETE"
});

Missing Authorization header when send http request from browser

I have an application in nodejs with jwt authorization, when I send a get from posman the authentication header is found but when I send it from the browser, the authorization header is missing.
Here is the node code, I'm trying to get the authorization header in the verifyToken method, but is not there:
'use strict';
var SwaggerExpress = require('swagger-express-mw');
var app = require('express')();
module.exports = app; // for testing
var _ = require('lodash');
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var config = {
appRoot: __dirname // required config
};
app.set('superSecret', config.secret); // secret variable
// bootstrap database connection and save it in express context
app.set("models", require("./api/model"));
var a = app.get("models").Role;
var repositoryFactory = require("./api/repository/RepositoryFactory").init(app);
var verifyToken = function (req, res, next) {
// verify token and read user from DB
// var token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiTm9tYnJlVXN1YXJpbyI6ImQiLCJQYXNzd29yZCI6IiQyYSQxMCRYS3BJM2ZDRVFoSzVKUFBQWEdIVVZPbUVPQTZsRVRoZDRtWHl4a0tDeGtUcEhvY0U0UTNILiIsImNyZWF0ZWRBdCI6IjIwMTYtMDktMDVUMTg6Mjk6MTYuMDAwWiIsInVwZGF0ZWRBdCI6IjIwMTYtMDktMDVUMTg6Mjk6MTYuMDAwWiIsInByb2Zlc2lvbmFsSWQiOm51bGwsInByb2Zlc2lvbmFsIjpudWxsLCJpYXQiOjE0NzMyNTczMjcsImV4cCI6MTQ3MzI5MzMyN30.CKB-GiuvwJsDAVnKsWb1FktI9tJY57lSgPRVEfW3pts';
var token = req.headers.authorization;
jwt.verify(token, 'shhhhh', function (err, decoded) {
if (err) {
res.status(403).json({ success: false, message: 'Failed to authenticate token.' });
} else {
// if everything is good, save to request for use in other routes
req.user = decoded;
next();
}
});
};
SwaggerExpress.create(config, function (err, swaggerExpress) {
if (err) { throw err; }
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-CSRF-Token, X-Requested-With, Origin, client-security-token, X-Requested-With, Content-Type, Accept, Authorization");
res.setHeader('Content-Type', 'application/json');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.use(verifyToken);
// install middleware
swaggerExpress.register(app);
var port = process.env.PORT || 10010;
app.listen(port);
});
I don't know what configuration I'm missing.
The issue was that I was trying to get the authorization token from the OPTIONS method, this method is sent before the actual get, port, put etc, when is a CORS request. So I was trying to get the authorization header from it and it was not there and the method failed.
The solution was to set in the verify token method a validation like this:
if (req.method !== OPTIONS){
}
I think it is easier if you can change the code in verifyToken function : var token = req.headers.authorization; become var token = req.headers.authorization || req.query.access_token || req.body.access_token;
So in the browser, you can add token in "access_token" query param to authenticate in server instead of setting the header.
Hope it is helpful for you !
You need to set those headers in your browser, try use this chrome plugin called ModHeader https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj
Try adding the following code in .htaccess. Apache removes the Authorization Header. This will ensure it is not removed.
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

Angular $http POST unable to send data to expressjs

I'm trying to post data from angular to express, however, eachtime I make the post request I get this error.
OPTIONS http://localhost/post/ net::ERR_CONNECTION_REFUSED(anonymous function) # angular.js:11209s # angular.js:11002g # angular.js:10712(anonymous function) # angular.js:15287m.$eval # angular.js:16554m.$digest # angular.js:16372m.$apply # angular.js:16662(anonymous function) # angular.js:24283m.event.dispatch # jquery.js:4670r.handle # jquery.js:4338
controller.js:29
and the errorCallback response object is:
Object {data: null, status: -1, config: Object, statusText: ""}
I did some tweaking looking at other similar questions on SO, like adding header, content-type etc. But no luck there.
What seems to be the problem here.
Thanks
Controller.js
word.add = function(){
console.log(word.name );
$http({
method:'POST',
url:'http://localhost/post/',
data :word.name,
headers: {'Content-Type': 'application/json'}
}).then(function successCallback(response){
console.log(response);
console.log("Successful");
},function errorCallback(response){
console.log(response);
console.log("Unsuccessful");
});
};
Relevant code excerpt from app.js
var routes = require('./routes/index');
app.all('/*', function (request, response, next) {
response.header("Access-Control-Allow-Origin", "*");
response.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
response.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
next();
});
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/post', routes);
index.js
var express = require('express');
var router = express.Router();
router.post('/post', function(request, response){
console.log(request.body.name);
response.send('Reached post');
});
module.exports = router;
Edit:
Hi, I've already tried and added the content-type header in my response.
Still,It's the same error.
The same code works fine while I use this method to post.
$http.post('/post',{data: word.name}).success(function(response) {
console.log("success");
}).error(function(err){
console.log("failure")
});
expressjs listing at 9000 port by default. So, you post url should be http://localhost:9000/post/
You must enable CORS on your server. Since the port is different on the same server it will treat it like a cross domain request.
http://enable-cors.org/server_expressjs.html

Node.js + Backbone collection json

I have a weird behavior in my current project. I am using Node.js in the backend and Backbone.js in the frontend. My Node.js application uses express for restful services. If I navigate to the path 127.0.0.1:999/users, everything is fine and the json data can be parsed correctly.
Actually my frontend looks like this:
//MODELS
var PersonList = Backbone.Collection.extend({
url: "http://127.0.0.1:9999/users"
});
//VIEWS
var PersonListView = Backbone.View.extend({
el : "#page",
render: function(){
var thisView = this;
var personList = new PersonList();
personList.fetch({
success: function(users, xhr){
$(thisView.el).html(users);
},
error: function(err)
{
console.log(err);
}
});
}
});
My backend looks as follows:
var express = require("express");
var app = express();
var users = [{id: 0,email: "user1#gmail.com"},
{id: 1,email: "userxx#gmail.com"},
{id: 2,email: "user123#gmail.com"}];
app.get("/users", function(request, response){
response.send(users);
});
app.listen(9999);
The fetch function does not fire the success event :(.
Any ideas what I am doing wrong?
Solved:
The problem is at the backend. Backbones request origin header is not accepted. Add the following code to your express application to get it work. In production make sure to store your allowed hosts in a separate configuration.
app.use(function(req, res, next){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With, X-Authtoken, Content-Type");
res.header("Access-Control-Allow-Methods", "HEAD, GET, POST, PUT, DELETE");
next();
});

Categories