Call SOAP API from nodejs and use(json) response data - javascript

I call a SOAP API from POSTMAN it is working fine. Now I want to use it with Node.js(nextjs).
This is how i am calling API and what I am getting.
How i will call this and get a json response?
Now i am calling like this-
const xml =
"<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><HourlyTransactions xmlns='https://secure.myterminals.com/ConfigStatusSyncService'><StartTime>2020-12-17 00:00</StartTime><EndTime>2020-12-18 00:00</EndTime><Login></Login><Password></Password></HourlyTransactions></soap:Body></soap:Envelope>";
let res = await fetch(
"https://secure.myterminals.com/ConfigStatusSyncService/DataQuery.asmx",
{
method: "POST",
headers: { "Content-Type": "text/xml" },
body: xml,
}
);
console.log(res);

I hope this can help I would use the easey-soap-request and here is an example.
import soapRequest from "easy-soap-request";
const url = "https://my-soap-server";
const sampleHeaders = {
"Content-Type": "text/xml;charset=UTF-8",
SOAPAction: "https://my-soap-action/something"
};
const xml = `<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
<soap:Body>
<HourlyTransactions xmlns='https://secure.myterminals.com/ConfigStatusSyncService'>
<StartTime>2020-12-17 00:00</StartTime><EndTime>2020-12-18 00:00</EndTime><Login></Login><Password></Password></HourlyTransactions>
</soap:Body>
</soap:Envelope>`;
async function makeRequest() {
const { response } = await soapRequest({
url: url,
headers: sampleHeaders,
xml: xml,
timeout: 1000
});
const { headers, body, statusCode } = response;
console.log(headers);
console.log(body);
console.log(statusCode);
document.body.innerHTML = body;
}
makeRequest();
This is the example I found HERE

I would rather use easy-soap-request package.
Here's a working example:
const soapRequest = require('easy-soap-request');
const url = 'https://secure.myterminals.com/ConfigStatusSyncService/DataQuery.asmx';
const sampleHeaders = {
'Content-Type': 'text/xml',
// 'soapAction': '' //FILL_HERE If Needed
};
const xmlSoapEnvelope = "<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><HourlyTransactions xmlns='https://secure.myterminals.com/ConfigStatusSyncService'><StartTime>2020-12-17 00:00</StartTime><EndTime>2020-12-18 00:00</EndTime><Login></Login><Password></Password></HourlyTransactions></soap:Body></soap:Envelope>";
(async () => {
try {
const {
response
} = await soapRequest({
url: url,
headers: sampleHeaders,
xml: xmlSoapEnvelope,
timeout: 1000
});
const {
headers,
body,
statusCode
} = response;
console.log('soap headers:', headers);
console.log('soap body:', body);
}
catch(e) {
console.log("Error Due to: ", e)
}
})()

Related

I get unknown path components: in messenger api

My api is as follows..
const { URL, URLSearchParams } = require("url");
async callSendApi(requestBody) {
let url = new URL(`${API_URL}/${PAGE_ID}/messages`);
url.search = new URLSearchParams({
access_token: `${PAGE_ACCESS_TOKEN}`,
});
console.warn("Request body is\n" + JSON.stringify(requestBody));
let response = await axios.post(url, {
headers: { "Content-Type": "application/json" },
body: JSON.stringify(requestBody),
});
if (!response.ok) {
consoleconst`Unable to call Send API: ${response.statusText}`,
await response.json();
}
}
The error I get :
message: 'Unknown path components: /messagesaccess_token="access_token"
I cannot find any wrong in this api. but still I get above error.. so I tried following...
async callSendApi(requestBody) {
let url = new URL(`${API_URL}/${PAGE_ID}/messages`);
console.warn("Request body is\n" + JSON.stringify(requestBody));
let response = await axios.post(url, {
headers: { "Content-Type": "application/json" },
body: JSON.stringify(requestBody),
access_token: `${PAGE_ACCESS_TOKEN}`,
});
if (!response.ok) {
consoleconst`Unable to call Send API: ${response.statusText}`,
await response.json();
}
}
then I get a error saying that cannot set headers after sending to the client..
please help!

Converting C# syntax HTTP call to JS syntax call

I got an HTTP call implemented with C# which calls to an Azure API:
public async Task<string> CheckPipelineRunStatus(string pipelineId, string pipelineRunId, CancellationToken cancellationToken = default)
{
string responseBody = "";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", _token))));
var requestUrl = $"https://dev.azure.com/{_organization}/{_project}/_apis/pipelines/{pipelineId}/runs/{pipelineRunId}?api-version={_api_version}";
using (HttpResponseMessage response = await client.GetAsync(requestUrl, cancellationToken))
{
response.EnsureSuccessStatusCode();
responseBody = await response.Content.ReadAsStringAsync();
}
}
return responseBody;
}
I need to do the same call in a Javascript call and I'm not sure how exactly am I suppose to send the Authorization header.
Here's what I got so far without the header (question in comment inside the code):
async function checkPipelineStatus(url)
{
var params = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
//is the auth supposed to be here? what to do with that 64base string?
}
};
const fetchResult = await fetch(url, params);
const result = await fetchResult.text();
if (!fetchResult.ok)
{
throw result;
}
return result;
}
As requested, here's your JavaScript code with the header inserted:
async function checkPipelineStatus(url)
{
let base64Credentials = btoa(':' + _token);
var params = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
// Insert your own Base64 credentials here:
'Authorization': `Basic ${base64Credentials}`
}
};
const fetchResult = await fetch(url, params);
const result = await fetchResult.text();
if (!fetchResult.ok)
{
throw result;
}
return result;
}

Error when page loads, instead of after form submit?

When I open my local host, I am getting the following error Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'Window': Failed to parse URL from //at getData ((index):60)
Which is pointing to these lines of code
const response = await fetch(url, {
&
getData(`/${url}`)
I'm not sure why I am getting this error when I load the page, as should I only get something like this when I search for something?
This is the larger block of code I am referring to:
document.getElementById('search').addEventListener('submit', function(e) { e.preventDefault(); getData(); })
const form = document.getElementById('Submit')
var formResult = new FormData(form);
const url = '/' + encodeURIComponent(formResult.get("search"));
async function getData(url = '', data = {}) {
const response = await fetch(url, {
method: 'GET',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
},
});
return response.json();
}
getData(`/${url}`)
.then(data => {
console.log(data);
})
Any insight would be appreciated.
for clarity on backend:
app.get('/:url', async function (req, res) {
console.log(req.params.url);
try {
await whoisssubmit.init();
const site = await whoisssubmit.open(decodeURIComponent(req.params.url));
const data = await site.analyze();
return res.status(200).json(data);
} catch (ex) {
console.log(ex);
return res.status(500).json({ message : "Oops." });
}});
Actually, you are calling getData() at the end of the snippet that you provided.
// Add url
const url = 'urlToApi';
document.getElementById('search').addEventListener('submit', function(e) { e.preventDefault(); getData(url).then(response => console.log(response)); })
async function getData(url = '', data = {}) {
const response = await fetch(url, {
method: 'GET',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
},
});
return response.json();
}

Getting pdf file from api response

I am calling an api and getting pdf in return.
fetch(`api` + guid, {
method: "GET",
headers: {
"Accept": "application/octet-stream",
"Authorization": "Bearer " + token,
},
responseType: 'arraybuffer',
})
.then((res) => res.text())
.then((data) => {
fs.writeFileSync('file.pdf', data);
});
I get the pdf file but the issue is the pdf file is always empty. But when I accept response as json, it works fine.
I found similar problems like this but none of the solution worked for me yet.
It would be great if someone can point out the issue.
I found the issue.
As I am using fetch not Axios.
We cannot pass responseType as Fetch's option.
fetch(`api` + guid, {
method: "GET",
headers: {
"Accept": "application/octet-stream",
"Authorization": "Bearer " + token,
},
// responseType: 'arraybuffer' //#1 remove this,
})
Instead the response in itself can be passed as arraybuffer as below.
.then((res) => res.arraybuffer())
instead of
.then((res) => res.text())
Now instead of directly using the response to write our pdf file. We can change the data to base64 string and decode it back again to create our pdf file. I used base64ToPdf npm package to handle that.
.then(data => {
var base64Str = Buffer.from(data).toString('base64');
base64.base64Decode(base64Str, "file.pdf");
})
I hope this help others. :)
Change res.arraybuffer() to res.arrayBuffer()
Below is the working code with webdriverio-
var headers = {
Authorization: "Bearer " + accessToken,
Accept: 'application/pdf'
}
fetch(
apiurl,
{
headers: {
Accept: "application/octet-stream",
Authorization: "Bearer " + accessToken
},
},
)
.then((res) => {
if (!res.ok) {
return res.status.toString()
}
return res.arrayBuffer()
})
.then((data) => {
var base64Str = Buffer.from(data).toString('base64');
base64.base64Decode(base64Str, filename);
})
.catch(
(err) => {
return err.Message;
})
Here's example which works for me:
async createPdf(context, data) {
let url = new URL(baseURL + '/invoice/createPdf');
url.search = new URLSearchParams({
id: data
})
await fetch(url, {
method: 'GET',
headers: {
'Authorization': "Bearer " + localStorage.getItem("jwt"),
'Accept': 'application/octet-stream'
},
}).then((res) => res.arrayBuffer())
.then(data => {
var base64Str = Buffer.from(data).toString('base64');
var binaryString = window.atob(base64Str);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
var arrBuffer = bytes;
var newBlob = new Blob([arrBuffer], { type: "application/pdf" });
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(newBlob);
return;
}
data = window.URL.createObjectURL(newBlob);
var link = document.createElement('a');
document.body.appendChild(link);
link.href = data;
link.download = "Faktura.pdf";
link.click();
window.URL.revokeObjectURL(data);
link.remove();
})
}
In my case, the response is same as yours and I'm trying to convert it to a pdf file so that I can preview it on the UI.
For this, I need to fetch the URL already present in the response which is of type blob... to fetch the URL I did URL.createObjectURL(myblob)
const [url,seturl] = useState('');
response
.then((resp) => resp.blob())
.then((myBlob) => {
seturl(URL.createObjectURL(myBlob)); //<-- use this for fetching url from your response
console.log(myBlob);
})
.catch((err) => {
console.log(err.message());
});

Axios request adding URL variable to localhost URL

I have a GET request Axios:
const fetchData = () => {
axios( {
method: "GET",
url: inputData.cUrl,
headers: { "content-type": "text/html" }
} ).then( ( response ) => {
const parser = new DOMParser();
const doc = parser.parseFromString( response, "text/html" );
console.log( doc );
} ).catch( e => console.log( e ) );
};
However, if inputData.cUrl is "www.google.com", the request will fail with the error message of
"GET http://localhost:3000/www.google.com 400 (Header required)".
2 questions.
Why does it append the url to the end of my localhost url? I want the get request to only go to the url the user puts in, not appended to my localhost.
And what does (Header required) mean? Never seen this with axios before.
Thank you for your help!
You need to add the http protocol in front of the URL. Here you go.
const inputData = {};
inputData.cUrl = 'https://www.google.com';
const fetchData = () => {
axios({
method: 'GET',
url: inputData.cUrl,
headers: {
'content-type': 'text/html'
}
})
.then(response => {
const parser = new DOMParser();
const doc = parser.parseFromString(response, 'text/html');
console.log(doc);
})
.catch(e => console.log(e));
};
you can ignore this because the Request was going to your server instead of 'www.google.com'

Categories