I am trying to make a SOAP call through node.js and am getting the below error:
ReferenceError: $http is not defined
Here is my code, everything else appears to work until it fails at the last line:
//Import the `assert` module to validate results.
var assert = require('assert');
var SoapRequestXML='<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:_5="https://clients.mindbodyonline.com/api/0_5">\r\n' +
'<soapenv:Header/>\r\n' +
'<soapenv:Body>\r\n' +
'<_5:GetClasses>\r\n' +
'<_5:Request>\r\n' +
'<_5:SourceCredentials>\r\n' +
'<_5:SourceName>SOURCECREDENTIALS</_5:SourceName>\r\n' +
'<_5:Password>PASSWORD</_5:Password>\r\n' +
'<_5:SiteIDs>\r\n' +
'<_5:int>-99</_5:int>\r\n' +
'</_5:SiteIDs>\r\n' +
'</_5:SourceCredentials>\r\n' +
'</_5:Request>\r\n' +
'</_5:GetClasses>\r\n' +
'</soapenv:Body>\r\n' +
'</soap:Envelope>';
var options = {
//Define endpoint URL.
url: "https://api.mindbodyonline.com/0_5/ClassService.asmx",
//Define body of POST request.
body: SoapRequestXML,
//Define insert key and expected data type.
headers: {
'POST': 'https://api.mindbodyonline.com/0_5/ClassService.asmx?wsdl HTTP/1.1',
'Accept-Encoding': 'gzip,deflate',
'Content-Type': 'text/xml;charset=UTF-8',
'SOAPAction': '"http://clients.mindbodyonline.com/api/0_5/GetClasses"',
'Content-Length': '594',
'Host': 'api.mindbodyonline.com',
'Connection': 'Keep-Alive',
'User-Agent': 'Apache-HttpClient/4.1.1 (java 1.5)'
}
};
//Define expected results using callback function.
function callback(error, response, body) {
//Log status code to Synthetics console.
console.log(response);
//Verify endpoint returns 200 (OK) response code.
assert.ok(response.statusCode == 200, 'Expected 200 OK response');
//Parse JSON received from Insights into variable.
//
var parseString = require('xml2js').parseString;
var XMLReSULT = response.body;
parseString(XMLReSULT, function (err, result) {
console.dir(result);
});
//Log end of script.
console.log("End reached");
}
//Make GET request, passing in options and callback.
$http.post(options, callback);
Any help is appreciated, I am very new at this.
Like previous comments implied, $http is not defined, and you cant use var $http = require('http') because nodes http does not have a post method. You will need to do a little refactoring. I think you're looking for something like this.
var assert = require('assert')
var http = require('http')
var parseString = require('xml2js').parseString;
var SoapRequestXML='<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:_5="https://clients.mindbodyonline.com/api/0_5">\r\n' +
'<soapenv:Header/>\r\n' +
'<soapenv:Body>\r\n' +
'<_5:GetClasses>\r\n' +
'<_5:Request>\r\n' +
'<_5:SourceCredentials>\r\n' +
'<_5:SourceName>SOURCECREDENTIALS</_5:SourceName>\r\n' +
'<_5:Password>PASSWORD</_5:Password>\r\n' +
'<_5:SiteIDs>\r\n' +
'<_5:int>-99</_5:int>\r\n' +
'</_5:SiteIDs>\r\n' +
'</_5:SourceCredentials>\r\n' +
'</_5:Request>\r\n' +
'</_5:GetClasses>\r\n' +
'</soapenv:Body>\r\n' +
'</soap:Envelope>';
var options = {
hostname: 'api.mindbodyonline.com',
port: 80,
path: '/0_5/ClassService.asmx',
method: 'POST',
headers: {
'Accept-Encoding': 'gzip,deflate',
'Content-Type': 'text/xml;charset=UTF-8',
'SOAPAction': '"http://clients.mindbodyonline.com/api/0_5/GetClasses"',
'Content-Length': '594',
'Connection': 'Keep-Alive',
'User-Agent': 'Apache-HttpClient/4.1.1 (java 1.5)'
}
}
var req = http.request(options, (res) => {
var data;
res.setEncoding('utf8');
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
parseString(data, function(err, result) {
console.log(result);
});
console.log('End reached')
});
});
req.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
});
req.write(SoapRequestXML);
req.end();
Related
The following code is with the Dropbox API, it worked during testing but when I added the "Content-Type":"application/json" in the parameters it broke.
https.request(options, function(resp){
let creds = [];
let ts = "";
resp.on('data', function(body){
creds.push(body);
let jsonarray = Array.prototype.slice.call(creds, 0).toString().split(",");
let token = "Bearer " + jsonarray[0].substring(jsonarray[0].indexOf(':') + 3, jsonarray[0].length - 1);
ts = token;
});
resp.on('end', function(){
let connectfilelist = {
hostname: 'api.dropboxapi.com',
path: '/2/files/list_folder',
method: 'POST',
headers: {Authorization: ts,
"Content-Type", "application/json"}
};
https.request(connectfilelist, function(resp){
let flist = [];
resp.on('data', function(chunk){
flist.push(chunk.toString());
});
resp.on('end', function(){
console.log(flist);
res.render('mydropbox', flist);
});
}).end(bodyParams);
});
}).end(bodyParams);
This is the error I get when i omit that parameter:
[ 'Error in call to API function "files/list_folder": This function requires its argument in the HTTP request body, but your request body is empty.' ]
When I include the Content-Type, it throws this:
[ 'Error in call to API function "files/list_folder": request body: could not decode input as JSON' ]
I think that the way I am stating the parameters might be in a string and not JSON format, but I am not sure where I would change something.
I'm struggling with dealing with my fetch() POST request. It's working successfully, and I can see the data just fine and work with it - but only within the fetch() call. I want to pass data back to App.js (I keep my fetch() API in its own utility module .js file)... but the timing is off. Based on console log debugging, it looks like the function that contains the fetch is returning to the original call before the fetch fully resolves.
These are the console results. The success/text object is what I return from the N4RecordScan.submit() function which contains my fetch(). Then a few lines later, we see the promise resolve. So my App.js is left hanging with no data.
I'd appreciate any guidance!! I feel like I'm close!
{success: "", text: ""}
Processing final response.
Fetch finished loading: OPTIONS
{argo:gateresponse: {…}, status: "0", statusid: "OK"}
Here'sa snippet from my App.JS which calls and processes the fetch function further down.
processResponse(myResponseObject) {
this.setState({
responseAlerts: this.state.responseAlerts.push(myResponseObject)
});
console.log('Processing final response. '+ myResponseObject.success + ' ' + myResponseObject.text);
}
sendRequest() {
let response = N4RecordScan.submit(this.interpolateRequest(), this.state.server, this.state.endpoint);
this.processResponse(response);
}
Here's the function where my fetch() resides:
export const N4RecordScan = {
submit(data, server, endpoint) {
let headers = new Headers();
let success = '';
let text = '';
headers.append('Content-Type', 'text/xml');
headers.append('SOAPAction', 'basicInvoke');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
let dataPrefix = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:arg="http://www.navis.com/services/argobasicservice"><soapenv:Header/><soapenv:Body><arg:basicInvoke><arg:scopeCoordinateIds>APMT/USLAX/LAX/LAX</arg:scopeCoordinateIds><arg:xmlDoc><![CDATA[';
let dataSuffix = ']]></arg:xmlDoc></arg:basicInvoke></soapenv:Body></soapenv:Envelope>';
data = dataPrefix + data + dataSuffix;
console.log('about to send ' + data);
fetch(server + endpoint, {
body: data,
method: 'POST',
mode: 'cors',
headers: headers,
credentials: 'include'
})
.then(function(response){
return response.text();
/* if (response.status === 200 || response.status === 0) {
// Success!
console.log('Success: ' + response.text());
return {
success: true,
text: response.text()
};
} else {
// Failure!
console.log('Fail: ' + response.statusText);
return {
success: false,
text: response.statusText
};
} */
} )
.then(function(rspText){
// The raw response contains decoded HTML tags... we need to clean that up.
// Remove dashes from the xml responses... the eventual js object wont like them
rspText = rspText.replace(/-/g, "");
// Convert the text response to XML
var parser = new DOMParser;
var dom = parser.parseFromString(
rspText,
'text/html');
var decodedString = dom.body.textContent;
// use the DOMParser browser API to convert text to a Document
var XML = new DOMParser().parseFromString(decodedString, "text/xml");
// and then use #parse to convert it to a JS object
var responseXmlObject = parse(XML);
console.log(responseXmlObject);
success = true;
text = responseXmlObject.messages;
alert(responseXmlObject.messages.messagedetail);
})
.catch(function(error) {
// Networking Failure!
console.log('NetworkFail: ' + error);
success = false;
text = error;
});
//.done();
console.log({
success: success,
text: text
});
return {
success: success,
text: text
};
}
};
The problem is you are mixing async and sync operations, you should be doing
processResponse(myResponseObject) {
this.setState({
responseAlerts: this.state.responseAlerts.push(myResponseObject)
});
console.log('Processing final response. '+ myResponseObject.success + ' ' + myResponseObject.text);
}
sendRequest() {
N4RecordScan.submit(this.interpolateRequest(), this.state.server, this.state.endpoint)
.then(function (response){
this.processResponse(response);
})
}
,
export const N4RecordScan = {
submit(data, server, endpoint) {
let headers = new Headers();
let success = '';
let text = '';
headers.append('Content-Type', 'text/xml');
headers.append('SOAPAction', 'basicInvoke');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
let dataPrefix = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:arg="http://www.navis.com/services/argobasicservice"><soapenv:Header/><soapenv:Body><arg:basicInvoke><arg:scopeCoordinateIds>APMT/USLAX/LAX/LAX</arg:scopeCoordinateIds><arg:xmlDoc><![CDATA[';
let dataSuffix = ']]></arg:xmlDoc></arg:basicInvoke></soapenv:Body></soapenv:Envelope>';
data = dataPrefix + data + dataSuffix;
console.log('about to send ' + data);
return fetch(server + endpoint, {
body: data,
method: 'POST',
mode: 'cors',
headers: headers,
credentials: 'include'
})
.then(function(response){
return response.text();
/* if (response.status === 200 || response.status === 0) {
// Success!
console.log('Success: ' + response.text());
return {
success: true,
text: response.text()
};
} else {
// Failure!
console.log('Fail: ' + response.statusText);
return {
success: false,
text: response.statusText
};
} */
} )
.then(function(rspText){
// The raw response contains decoded HTML tags... we need to clean that up.
// Remove dashes from the xml responses... the eventual js object wont like them
rspText = rspText.replace(/-/g, "");
// Convert the text response to XML
var parser = new DOMParser;
var dom = parser.parseFromString(
rspText,
'text/html');
var decodedString = dom.body.textContent;
// use the DOMParser browser API to convert text to a Document
var XML = new DOMParser().parseFromString(decodedString, "text/xml");
// and then use #parse to convert it to a JS object
var responseXmlObject = parse(XML);
console.log(responseXmlObject);
success = true;
text = responseXmlObject.messages;
alert(responseXmlObject.messages.messagedetail);
})
.catch(function(error) {
// Networking Failure!
console.log('NetworkFail: ' + error);
success = false;
text = error;
})
.then(function () {
console.log({
success: success,
text: text
});
return {
success: success,
text: text
};
})
//.done();
}
};
You should be returning the promise from fetch inside the submit function so that the function in App.js can wait until fetch is done to do processing
Now I have a question like this:
I created a server with node.js ,and the server have receive a ajax request.With the data received from ajax ,node.js send a post request to another server. Now I have got the data from another server and the main question is how to send the data back to ajax, I have tried many ways but it does not work.
Can somebody help me on this issue?
here is my code
====ajax request
$.ajax({
type: "POST",
url: 'http://localhost:8888', // 这里要改成服务器的地址
data: userData,
success: function (data) {
console.log(data);
}
})
====
http.createServer(function (req, res) {
if (req.url == '/') {
var data = '';
var imdata;
util.log(util.inspect(req));
util.log('Request recieved: \nmethod: ' + req.method + '\nurl: ' + req.url);
req.on('data', function (chunk) {
imdata = querystring.parse(data += chunk);//转成对象的格式
})
req.on('end', function () {
var myIm = new ServerApi('e782429e48cb99f44b9c5effe414ac72', 'b88b9f2a2f74');
myIm.createUserId(imdata, function (err, data) {
//createUesrId is a api to deal with post request
console.log(data);//the data have received from another server,and now i do not know how to return the data to ajax success function
})
})
====the api to create user id with post requeset
ServerApi.prototype.postDataHttps = function (url, data, callback) {
this.checkSumBuilder();
var urlObj = urlParser.parse(url);
var httpHeader = {
'AppKey': this.AppKey,
'Nonce': this.Nonce,
'CurTime': this.CurTime,
'CheckSum': this.CheckSum,
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
'Content-Length': Buffer.byteLength(data)
};
var options = {
hostname: urlObj.hostname,
port: 80,
path: urlObj.path,
method: 'POST',
headers: httpHeader
};
var that = this;
var req = http.request(options, function (res) {
res.setEncoding('utf8');
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.on('data', function (chunk) {
if (Object.prototype.toString.call(callback) === '[object Function]') {
var result = JSON.parse(chunk);
callback.call(that, null, result);
return result;
}
});
});
var postData = querystring.stringify(data);
req.write(postData);
req.end(data);
req.on('error', function (err) {
if (Object.prototype.toString.call(callback) === '[object Function]') {
callback.call(that, err, null);
}
});
}
ServerApi.prototype.createUserId = function (data, callback) {
var url = 'https://api.netease.im/nimserver/user/create.action';
var postData = {
'accid': data['accid'] || '',
'name': data['name'] || '',
'props': data['props'] || '',
'icon': data['icon'] || '',
'token': data['token'] || ''
};
this.postDataHttps(url, postData, callback);
}
On your server code. The one with http.createServer(function (req, res) {...}
Notice how you got a req and res parameter?
So on event end, that is req.on('end' function... Right after the line where you got a comment saying the 'data is received from another server', you can do something like;
res.writeHead(/*HTTP_RESPONSE_CODE_FOR_AJAX_CLIENT=*/200);
res.end('Done');
to send a response back to your client with HTTP response code = 200 and the message in the HTTP body would be 'Done'. Note that, there are quite a number of things you can do with the response object, you may want to see the documentation for more information.
See:
https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers
OR
(中文版)
http://nodeapi.ucdok.com/api/http.html#http_class_http_serverresponse_7847
Quick explanation in Chinese:
在服务器的代码req.on('end'...那里, 你可以用resobject打回给你的AJax client.
I have a node.js server and I'm making GET requests.
The arguments passed using Python's requests and JavaScripts's request are received properly.
// Python
requests.get(url, data=data)
// JS
request.get({url: url, form:form}, function(){})
But the data is not received when I make the request from a browser like: url?a=1&b=2.
How do I fix it?
This is the function that I'm using to parse the form data:
function extractData(request, response, callback, options) {
var jsonString = '';
request.on('data', function(data) {
jsonString += data;
});
request.on('end', function() {
data = qs.parse(jsonString);
callback(request, response, data, options);
});
}
data is blank when I pass the arguments from URL.
I hope this will be helpful and below code is working to me
var options = {
host: 'services.com',
path: '/app/server.js/index/',
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': data.length
}
};
var req = https.request(options, function(res) {
var msg = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
msg += chunk;//'chunk' response from server
if(chunk != "available")
{
var mail = {
from: "abc#gmail.com",
to: "ddd#gmail.com",
subject: "Alert! from production server",
html: "<p>Hi Team,</p> <p>Alert! production server is down.</p><p>Thanks,<br/>Maintenance Team</p>"
};
transporter.sendMail(mail, function(error, response){
if(error){
console.log(error);
//res.send({ "result" : "failure" });
}else{
console.log("Message sent: " + response);
//res.send({ "result" : "success" });
}
});
}
});
res.on('end', function() {
//console.log(JSON.parse(msg));
console.log(msg);
});
I have array with data (objects):
var data = [
{"name":"Jon",
"age":22},
{"name":"Ioan",
"age":42},
{"name":"Jem",
"age":33},
... other more then 100 items
]
var http = require('http');
var options = {
hostname: 'localhost',
port: 80,
path: '/users',
method: 'POST',
headers: {
'Content-Type': 'application/json'
} };
//I create following function:
function sendData(data) {
var req = http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.write(JSON.stringify(data));
req.end();
}
//end try send for each array item:
for (var i=0; i<data.length;i++) {
sendData(data[i]);
}
But sended only first item from array.
How I can send each item as POST request?
May be the best solution may suggest.
If requests will execute as async it will be better.
UPDATE:
I find better solution with async module.
Add following code:
var async = require("async");
var tasks = [];
for (i=0;i<result.length;i++) {
tasks.push(sendRequest(data[i]));
}
async.parallel(tasks, function(){
console.log("done");
});
And all request wat sended async.
Are you using jQuery?
If so you can use the $.post method along with a $.each method.
You could do something like
$.each(data, function(index, val) {
JSON.stringify(val);
$.post(url, val)
.done(function (data) {
alert("got " + data + " back");
});
});
Not the most concise, but it'll do the trick, and it'll do it asynchronously.
full dox here:
for $.post
for $.each