POST to express.js with 'Access-Control-Allow-Origin' - node.js

I'm a newbie to Node and Express. I can GET data from my server app but fail on POST.
I have the client side on "http://myapp.com" and the Node app on "http://myapp.com:34627".
This is the Node app:
var express = require('express'), app = express();
var result = {};
app.configure(function()
{
app.use(express.json());
app.use(express.urlencoded());
});
app.set("jsonp callback", true);
app.get('/get/users/:userid/:username',function(req,res)
{
var userID = req.params.userid;
var userName = req.params.username;
result = {
response: 'OK',
url_userid: userID,
url_username: userName
};
res.header('Access-Control-Allow-Origin','http://listasapp.in');
res.json(200,result);
});
app.post('/post/user',function(req,res)
{
console.log( req.body );
result = {
response: 'OK'
};
res.jsonp(200,result);
});
var server = app.listen(34627,function()
{
console.log( 'Server running at http://myapp.com:' + server.address().port );
});
$('#get-data').on('click tap',function()
{
var url = 'http://listasapp.in:34627/get/users';
url += '/24601';
url += '/junihh';
$.getJSON(url,function(rsp)
{
console.log( rsp );
});
});
And this is the client side:
$('#get-data').on('click tap',function()
{
var url = 'http://myapp.com:34627/get/users';
url += '/24601';
url += '/junihh';
$.getJSON(url,function(rsp)
{
console.log( rsp );
});
});
$('#post-data').on('click tap',function()
{
var dta = {
userid: '24601',
username: 'junihh'
};
$.ajax({
type: 'POST',
url: 'http://myapp.com:34627/post/user?callback=?',
data: dta,
dataType: 'jsonp',
success: function(rsp)
{
console.log( rsp );
},
error: function(jqXHR,textStatus,errorThrown)
{
console.log( jqXHR.status );
console.log( textStatus );
console.log( errorThrown );
}
});
});
I have a successful GET request but with the POST I get this error:
GET http://myapp.com:34627/post/user?callback=jQuery1110009652853850275278_1397958835486&userid=24601&username=junihh&_=1397958835487 404 (Not Found)
I'm stuck here, I don't figure out how to fix that error. Something wrong with my code ??
Thanks for any help or advise.

Finally I found the answer thanks to this post: https://github.com/visionmedia/express/blob/master/examples/cors/index.js
I add this portion of code to my Node app:
app.all('*',function(req,res,next)
{
if (!req.get('Origin')) return next();
res.set('Access-Control-Allow-Origin','http://myapp.com');
res.set('Access-Control-Allow-Methods','GET,POST');
res.set('Access-Control-Allow-Headers','X-Requested-With,Content-Type');
if ('OPTIONS' == req.method) return res.send(200);
next();
});

Related

How can I display the SOAP envelope in XML format in nodejs?

I have a simple SOAP service working using nodejs but I am having trouble figuring out how to build the correct envelope structure that is required for my project.
Is there a way to display the SOAP envelope in XML format that is sent to the server?
I also tried forceSoap12Headers:true` but it did not call v12 methods in my server. Any hints here would be great.
SERVER
"use strict";
var soap = require('soap');
var http = require('http');
var myService = {
ACME: {
ACMESoap: {
CalcFee: function(args, callback) {
callback({
"ns1:barcodeReceive": args.cardNumber,
"ns1:requestId": args.requestId,
"ns1:calculatedFee": 0.15
});
},
LoadCard: function(args, callback) {
callback({
"ns1:barcodeReceived": args.cardNumber,
"ns1:requestId": args.requestId,
"ns1:transactionAmount": '100.00',
"ns1:currency": 'EUR'
});
}
},
ACMESoap12: {
CalcFee: function(args, callback) {
callback({
"ns1:barcodeReceived": args.cardNumber,
"ns1:calculatedFee": 0.15
});
},
LoadCard: function(args, callback) {
callback({
"ns1:barcodeReceived": args.cardNumber,
"ns1:transactionAmount": '100.00',
"ns1:currency": 'EUR'
});
}
}
}
};
var port = 7777;
var xml = require('fs').readFileSync('ACMEService.wsdl','utf8');
var server = http.createServer(function(request,response) {
response.end("404: Not Found: " + request.url);
});
console.log('Started server on port ' + port);
server.listen(port);
soap.listen(server,'/wsdl',myService, xml);
CLIENT
"use strict";
console.log('Started Client...');
const util = require('util')
var soap = require('soap');
var url = 'http://ACME.net:7777/wsdl?wsdl';
var args = {
requestId: '2833007',
cardNumber: '3452345234'
};
var args2 = {
requestId: '2833008',
cardNumber: '56345634563'
};
var options = {
forceSoap12Headers: true
};
soap.createClient(url, options, function(err,client) {
client.CalcFee(args,function(err, result, rawResponse) {
console.log(rawResponse);
// console.log(client.describe());
});
client.LoadCard(args2,function(err,result, rawResponse) {
console.log(rawResponse);
});
});
I figured out I can send the request back to the client to display.
SERVER
...
callback({
"tns:RECEIVED_ENVELOPE": args
});
...

Chunk/Stream API data using Node.js

We have requirement where we need to write a node application which can read URL of image from database (approx more than million). Use image-size npm package to retrieve image meta data like height, width. Here should be an API which can list out result.
I am able to console log data but when i convert it to API, i need to chunk data so it can start appearing on browser and i'm unable to do that and need help. Here is my code
var express = require('express');
var url = require('url');
var http = require('http');
var sizeOf = require('image-size');
const sql = require('mssql');
var app = express();
var port = process.env.PORT || 3000;
const hostname = 'localhost';
var config1 = {
user: '*********',
password: '*********',
server: '*********',
database: '*******',
port: 1433,
debug: true,
options: {
encrypt: false // Use this if you're on Windows Azure
}
};
app.get('/', function(req, res){
//res.writeHead(200, { 'Content-Type': 'application/json' });
var finalResult = [];
sql.close();
sql.connect(config1, function (err) {
if (err) console.log(err);
const request = new sql.Request()
var myQuery = `select imagename from media`;
request.stream = true;
request.query(myQuery);
request.on('row', row => {
//console.log('Image : ' + row.ImageUrl);
if (row.ImageUrl != ''){
if (row.ImageUrl.indexOf('http') < 0)
row.ImageUrl = "http:" + row.ImageUrl;
var options = url.parse(row.ImageUrl);
http.get(options, function (response) {
if (response.statusCode == 200)
{
var chunks = [];
response.on('data', function (chunk) {
chunks.push(chunk);
}).on('end', function() {
var buffer = Buffer.concat(chunks);
//console.log(options.href);
//console.log(sizeOf(buffer).height);
var result = {};
result.MaskUrl = row.MaskUrl;
result.ImageUrl = options.href;
result.Height = sizeOf(buffer).height;
result.Width = sizeOf(buffer).width;
result.statusCode = 200;
finalResult.push(result);
//console.log(result);
console.log(finalResult);
res.write(result, function(){
res.end();
});
});
}
else
{
var result = {};
result.MaskUrl = row.MaskUrl;
result.ImageUrl = options.href;
result.Height = 0;
result.Width = 0;
result.statusCode = response.statusCode;
finalResult.push(result);
console.log(result);
res.write(result, function(){
res.end();
});
}
});
}
})
request.on('error', err => {
console.log ('Error for ' + row.ImageUrl );
})
request.on('done', err => {
console.log('Last Time' + finalResult.length);
})
// request.query(myQuery,(err,result) =>{
// console.log(result);
// });
});
console.log('Last Time' + finalResult.length);
res.send(finalResult);
});
app.listen(port, hostname, function(){
console.log('ImageSize running on PORT: ' + port);
});
I tried res.write, res.end without any success.
The probable reason for your problem is that here:
res.write(result, function(){
res.end();
});
You end and close the request just after the first image is read.
I would rewrite the code a little and use some functional framework, like scramjet, to stream the data straight from the DB. As Nicholas pointed out it's not super easy to run your code so I'm writing blindly - but if you fix any of my obvious error this should just work:
First:
npm install scramjet JSONStream node-fetch
Next, try this code:
var express = require('express');
var sizeOf = require('image-size');
const sql = require('mssql');
var app = express();
var port = process.env.PORT || 3000;
const hostname = 'localhost';
const {DataStream} = require('scramjet');
const fetch = require('node-fetch');
const JSONStream = require('JSONStream');
var config1 = {
user: '*********',
password: '*********',
server: '*********',
database: '*******',
port: 1433,
debug: true,
options: {
encrypt: false // Use this if you're on Windows Azure
}
};
app.get('/', function(req, res, next){
// you should consider not doing these two lines on each request,
// but I don't want to mess you code...
sql.close();
sql.connect(config1, function (err) {
if (err) next(err);
res.writeHead(200, { 'Content-Type': 'application/json' });
const request = new sql.Request();
var myQuery = `select imagename from media`;
request.stream = true;
request.query(myQuery);
const stream = new DataStream();
request.on('row', row => stream.write(row));
stream.filter(
row => row.ImageUrl !== ''
)
.map(
async row => {
if (row.ImageUrl.indexOf('http') !== 0) // url must start with http.
row.ImageUrl = "http:" + row.ImageUrl;
const response = await fetch(row.ImageUrl);
let size = {width:0, height:0};
if (response.status === 200) {
const buffer = await response.buffer();
size = sizeOf(buffer);
}
return {
MaskUrl: row.MaskUrl,
ImageUrl: row.ImageUrl,
Height: size.height,
Width: size.width,
statusCode: response.status
};
}
)
.pipe(
JSONStream.stringify()
).pipe(
res
);
request.on('error', () => {
res.writeHead(500, { 'Content-Type': 'application/json' });
stream.end("{error:true}");
});
request.on('done', () => stream.end());
});
});
app.listen(port, hostname, function(){
console.log('ImageSize running on PORT: ' + port);
});

Web Digits Fabric Authentication

I am using digits web. I am using the cannonball example. I am running the below code on my local comptuter.
Heres my code of client side
<script>document.getElementById('digits-sdk').onload = function() {
Digits.init({ consumerKey: 'my consumer key' });
Digits.embed({
container: '#my-digits-container',
theme: {
/* Input fields borders */
},
phoneNumber: '+91',
})
.done(onLogin) /*handle the response*/
.fail(onLoginFailure);
};
function onLoginFailure(loginResponse) {
console.log('Digits login failed.');
//setDigitsButton('Verify again');
}
/* Validate and log use in. */
function onLogin(loginResponse){
// Send headers to your server and validate user by calling Digits’ API
//var oAuthHeaders = loginResponse.oauth_echo_headers;
var oAuthHeaders = parseOAuthHeaders(loginResponse.oauth_echo_headers);
$.ajax({
type: 'POST',
url: '/digits',
data: oAuthHeaders,
success: onDigitsSuccess
});
// setDigitsButton('Step 2.....');
}
function parseOAuthHeaders(oAuthEchoHeaders) {
var credentials = oAuthEchoHeaders['X-Verify-Credentials-Authorization'];
var apiUrl = oAuthEchoHeaders['X-Auth-Service-Provider'];
console.log(apiUrl);
return {
apiUrl: apiUrl,
credentials: credentials
};
}
function onDigitsSuccess(response) {
console.log(response.phoneNumber);
setDigitsNumber(response.phoneNumber);
}
function setDigitsNumber(phoneNumber) {
document.getElementById('notr').value = phoneNumber;
console.log('Digits phone number retrieved.');
}
</script>
In the above code I have changed the consumer key only. So ignore that.
And heres my server code
var express = require("express");
var app = express();
var router = express.Router();
var path = __dirname + '/static/';
app.use(express.static(__dirname + '/static'));
router.use(function (req,res,next) {
console.log("/" + req.method);
next();
});
router.get("/",function(req,res){
res.sendFile(path + "homepage9.html");
});
router.get("/about",function(req,res){
res.sendFile(path + "about.html");
});
router.get("/contact",function(req,res){
res.sendFile(path + "contact.html");
});
app.use("/",router);
app.use("*",function(req,res){
res.sendFile(path + "404.html");
});
app.listen(3000,function(){
console.log("Live at Port 3000");
});
var fs = require('fs');
var nconf = require('nconf');
var url = require('url');
var request = require('request');
router.post('/digits', function (req, res) {
console.log("digits entered")
var apiUrl = req.body['apiUrl']
var credentials = req.body['credentials']
var verified = true;
var messages = [];
if (credentials.indexOf('oauth_consumer_key="' + 'my consumer key' + '"') == -1) {
verified = false;
messages.push('The Digits API key does not match.');
}
var hostname = url.parse(req.body.apiUrl).hostname;
if (hostname != 'api.digits.com' && hostname != 'api.twitter.com') {
verified = false;
messages.push('Invalid API hostname.');
}
// Do not perform the request if the API key or hostname are not verified.
if (!verified) {
return res.send({
phoneNumber: "",
userID: "",
error: messages.join(' ')
});
}
// Prepare the request to the Digits API.
var options = {
url: apiUrl,
headers: {
'Authorization': credentials
}
};
// Perform the request to the Digits API.
request.get(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
// Send the verified phone number and Digits user ID.
var digits = JSON.parse(body)
return res.send({
phoneNumber: digits.phone_number,
userID: digits.id_str,
error: ''
});
} else {
// Send the error.
return res.send({
phoneNumber: '',
userID: '',
error: error.message
});
}
});
});
But on the node console i am getting
cannot read property 'apiUrl' of undefined.
on google chrome console i am getting
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
Can any one help of what I am doing wrong.
Also in the cannon ball example i found that it nowhere uses the consumer secret key. Why is that?

node request library return an error on api call

I'm using Bitly api to shorten links:
http://dev.bitly.com/links.html#v3_shorten
But then in the console log im getting an Error...
var Bitly = require('bitly');
var bitly = new Bitly('key');
module.exports = function(req, res) {
var term = req.query.text;
handleSearchString(term, req, res);
};
function handleSearchString(term, req, res) {
var response;
try {
response = sync.await(request({
url: 'https://api-ssl.bitly.com/v3/link/shorten',
qs: {
//link: term,
'access_token': key,
'longUrl': term,
},
timeout: 15 * 1000
}, sync.defer()));
} catch (e) {
res.status(500).send('\nError!\n');
return;
}
var html = '<p> ' + response + ' </p>';
res.json([{
body: html
}]);
};
Console.log outputs Error!,

Posting a Post through Facebook Graph Node JS

I'm currently looking to automate a few tasks by creating a custom application that allows me to easily post status updates on my Facebook page(not my personal timeline). My backend is running on NodeJS.
My client-side code has the following:
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxxxxxxxxxxx', // App ID
channelUrl : '//xxxxxxxxxxx, // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Additional init code here
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
console.log("You are signed into FB");
var access_token = FB.getAuthResponse()['accessToken'];
console.log('Access Token = ' + access_token);
FB.api('/me/accounts', function(response) {
for(var i=0;i <response.data.length;i++){;
var page = response.data[i];
if(page.id==my_id){
var page_token = page.access_token;
console.log(page_token);
var param = 'callback=?&username=' + GetURLParameter('username')+'&session='+ GetURLParameter('session')+'&access_token='+ page_token;
$.post(saveTokenEndpoint, param, function(data) {
console.log(data);
});
}
}
});
FB.api('/me', function(response) {
username = response.name;
userid = response.id;
$('#username').text('~Hi '+username+'!');
$(document).trigger('fbInit');
});
// connected
} else if (response.status === 'not_authorized') {
// not_authorized
login();
} else {
login();
// not_logged_in
}
});
};
// Load the SDK Asynchronously
( function(d) {
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement('script');
js.id = id;
js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
function login() {
FB.login(function(response) {
if (response.authResponse) {
console.log("You are signed into FB");
var access_token = FB.getAuthResponse()['accessToken'];
FB.api('/me', function(response) {
username = response.name;
userid = response.id;
$('#username').text('~Hi '+username+'!');
$(document).trigger('fbInit');
});
FB.api('/me/accounts', function(response) {
// handle response
for(page in response.data){
if(page.id==my_id){
var page_token = page.access_token;
console.log(page_token);
var param = 'callback=?&username=' + GetURLParameter('username')+'&session='+ GetURLParameter('session')+'&access_token='+ page_token;
$.post(saveTokenEndpoint, param, function(data) {
console.log(data);
});
}
}
});
} else {
// cancelled
}
}, {scope: 'publish_stream, manage_pages, offline_access'});
}
My server-side code:
// saves the token received for future use in posting
app.post('/api/saveToken',function(req,res){
var username = req.body.username;
var access_token = req.body.access_token;
var session = req.body.session;
user.findOne({
username: username,
session: session
},function(err, userObj){
if(userObj!=null){
userObj.token = access_token;
console.log(access_token);
userObj.save();
res.jsonp({status:'true'});
}else{
res.jsonp({status:'false'});
}
});
});
I'm using this method to post my posts on my page:
var data = querystring.stringify({
access_token: token,
message: message
});
var options = {
host: 'graph.facebook.com',
port: 443,
path: '/app_name/feed',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
};
var req = https.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log("body: " + chunk);
});
res.on('end', function(){ // see http nodejs documentation to see end
console.log("\nfinished posting message");
conObj.approval = 'published';
conObj.save();
});
});
req.on('error', function(e) {
console.error(e);
});
req.write(data);
req.end();
Current situation:
My code is working and i can actually see the posts on the wall of my page.
BUT
It does not appear to anyone else except myself.
HOW I GOT IT TO APPEAR PROPERLY TEMPORARILY:
When i copy the token directly from the Graph API Explorer(/me/accounts), I got it to work.
https://developers.facebook.com/tools/explorer?method=GET&path=me%2Faccounts
Ultimately, all i want to do is find a way to post a post on my page
I monitored the differences that was made through both tokens and have found no differences. Their scope was to the 'public' and 'everyone'.
Experts do advice! I find this all very puzzling.
I'm intending to try NodeJS facebook such as facebook-node-sdk and nodejs-facebook-sdk libraries if all else fails.
Thanks for the replies in advance!
You should do OAUTH server side, not client side.
Here is a working example of posting a post through the Facebook Graph API using node.js here: http://code.runnable.com/facebook/UTlPM1-f2W1TAABY
The only dependency you're not already using is request, which you should be using.

Resources