I have an API Server and NodeJs Server and when a file is requested NodeJs redirected the request to API Server
API Server Send the File as raw data to NodeJs
and Nodejs redirects the file to the browser
But when I checked the network data using wire shark the packet received at browser is not original as that from API Server (work in case of text files, but not in image, video, pdf, doc etc)
router.get('/GetCaseSupportDocument', function (req, res) {
var MyJsonData = {
DocId:parseInt(req.query.DocId) || 0
};
request({
url: 'http://somedomain/someurl', //URL to hit
method: 'POST',
json: MyJsonData
}, function (error, response, body) {
if (error) {
res.status(200).send('Failed');
} else {
res.status(200).send(body);
}
})
});
Can anyone tell why it changes between NodeJs to Browser?
Is there any better solution for this type of transmission?
Updated After finding solution . This works
router.get('/GetCaseSupportDocument', function (req, res) {
var MyJsonData = {
DocId:parseInt(req.query.DocId) || 0
};
request({
url: Url.CaseService + 'GetCaseSupportDocument', //URL to hit
method: 'POST',
json: MyJsonData
}).pipe(res);
})
There is a simple proxy using streams that you can try:
router.get('/GetCaseSupportDocument', function (req, res) {
var MyJsonData = {
DocId: parseInt(req.query.DocId) || 0
};
// updated the response
request({
url: 'http://somedomain/someurl', //URL to hit
method: 'POST',
json: MyJsonData
}).pipe(res);
});
More details with proxy-ing you can find on the request documentation https://github.com/request/request
Related
I am attempting to get data in the form of an image sent from elsewhere using multipartform, however when trying to understand this via the great sanctuary(stack overflow) there are missing elements I don't quite understand.
const options = {
method: "POST",
url: "https://api.LINK.com/file",
port: 443,
headers: {
"Authorization": "Basic " + auth,
"Content-Type": "multipart/form-data"
},
formData : {
"image" : fs.createReadStream("./images/scr1.png")
}
};
request(options, function (err, res, body) {
if(err) console.log(err);
console.log(body);
});
2 questions:
what is the variable auth, what do I initialize it to/where/how do I declare it
what is the url "api.LINK.com", is this just the site url where this code is on
After your comments I think I may be doing this wrong. The goal is to send data(an image) from somewhere else(like another website) to this node app, then the nodeapp uses the image and sends something back.
So that I would be the one creating the API endpoint
I have a node.js application served over https. I would like to call an API from that application. The API is also served over https and it has been generated using the express-generator.
Unfortunately the call never works. There is no error message. The call never reaches the API.
Strangely enough if I try to call another public API (e.g. https://api.publicapis.org/entries') that is working perfectly.
Here is my call:
const requestBody = {
'querystring': searchQuery,
};
const options = {
rejectUnauthorized: false,
keepAlive: false, // switch to true if you're making a lot of calls from this client
};
return new Promise(function (resolve, reject) {
const sslConfiguredAgent = new https.Agent(options);
const requestOptions = {
method: 'POST',
body: JSON.stringify(requestBody),
agent: sslConfiguredAgent,
redirect: 'follow',
};
fetch('https://192.168.112.34:3003/search', requestOptions)
.then(response => response.text())
.then(result => resolve(result))
.catch(error => console.log('error', error));
});
};
And here is the API which I would like to call:
router.post('/', cors(), async function(req, res, next) {
req.body;
queryString = req.body.querystring;
let data = JSON.stringify({
"query": {
"match": {
"phonetic": {
"query": queryString,
"fuzziness": "AUTO",
"operator": "and"
}
}
}
});
const { body } = await client.search({
index: 'phoneticindex',
body: data
});
res.send(body.hits.hits)
});
What is wrong with my API and/or the way I am trying to communicate with it?
UPDATE: I receive the following error in the fetch catch block: 'TypeError: Failed to fetch'
When I create a request in Postman I receive the expected response.
UPDATE 2: This is most probably an SSL related issue. The webapp is expecting an API with a valid certificate. Obviously my API can only have a self signed cert which is not enough here. How can I generate a valid cert for an API which is running on the local network and not publicly available?
UPDATE 3: I managed to make it work by changing the fetch parameters like this:
fetch(url, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
mode: 'cors',
body: raw,
agent: httpsAgent,
redirect: 'follow',
})
and on the API side I added the following headers:
'Content-Type': 'application/json',
'Access-Control-Allow-Origin' : 'https://localhost:2200',
'Access-Control-Allow-Methods' : 'POST',
'Access-Control-Allow-Headers' : 'Content-Type, Authorization'
I also added app.use(cors()) and regenerated the self-signed certificates.
My app works fine locally and I have a much more complicated app running on heroku. But I consistently get a 503 / H12 timeout when it tries to run a POST request. It takes two seconds locally. Any ideas?
The post route in question (uses a node.js sdk for aylien nlp api):
app.post('/apiRequest', (req, res) => {
const reqUrl = req.body.url;
aylienApi.combined({
'url': reqUrl,
'endpoint': ['language', 'sentiment', 'summarize']
}, function(error, result) {
if (error === null){
res.send(result.results)
}
})
})
The async POST request:
const postData = async (url = '', data = {}) => {
const res = await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
})
try {
const articleData = await res.json();
return articleData;
} catch (error) {
console.log('error', error)
}
}
I've read on the heroku documentation that it can be caused by large bits of data, but I'm only grabbing a small amount of JSON and send a url.
It turns out I had not uploaded by .env file with the api keys etc, as it was still in the gitignore file.
Silly me. But turns out the Aylien nlp api doesn't warn you if the key isn't set.
I am facing below issue with passing the parameters from the Express API to Request module URL.
In the below code Suppose I have the request details as
request_data.url = http://localhost:3000/interface/en/
When users enters the URL as http://localhost:3000/interface/en/123456
I wanted to send the 123456 to the line
url: request_data.url + acct,
Hence my final url for the request module becomes as http://localhost:3000/interface/en/123456
But my below code is not working , can someone help me here or suggest me what changes are requires
Code
app.get('/interface/:env/:acct', (req, res) => {
var acct = req.params.acct;
var env = req.params.env;
var hsResponse = request({
proxy: proxyUrl,
url: request_data.url + acct,
headers: request_data.headers,
method: request_data.method,
form: oauth.authorize(request_data)
}, function (error, response, body) {
res.setHeader('Content-Type', 'application/json');
res.send(body); //<-- send hsResponse response body back to your API consumer
});
});
Please use following code,
app.get('/interface/:env/:acct', (req, res) => {
var acct = req.params.acct;
var env = req.params.env;
// here you need to update your url
request_data.url = request_data.url + acct;
var hsResponse = request({
proxy: proxyUrl,
url: request_data.url ,
headers: request_data.headers,
method: request_data.method,
form: oauth.authorize(request_data)
}, function (error, response, body) {
res.setHeader('Content-Type', 'application/json');
res.send(body); //<-- send hsResponse response body back to your API consumer
});
});
I think you are using OAuth, where you passing form field to the request, which will need to authorize with existing mapped request_data like URL and other attributes.
Hope this will help you !!
When I request images using node request library of the given url, the images loaded are not complete. After storing the loaded image it looks like https://ibb.co/i5xVAR
However the request finishes without an error and has status code 200. For me it seems that the ssl connection gets closed. Other tools like browser or curl transfer the image complete.
const request = require('request');
const r1 = request({
url: 'https://open.hpi.de/files/f1d16619-9813-4d59-96b3-d84908929b23',
encoding: 'binary'
}, (err, response, body) => {
if (err) {
console.log(err);
return;
}
// complete file should be loaded
// content and body length should match
// read ECONNRESET should not be thrown
console.log('body length', body.length);
console.log('response content length', response.headers['content-length']);
});
The open.hpi.de host is closing the connection prematurely. You can add a Connection: keep-alive header to the request and the connection will remain open until the transfer is actually complete:
const request = require('request');
const r1 = request({
url: 'https://open.hpi.de/files/f1d16619-9813-4d59-96b3-d84908929b23',
encoding: 'binary',
headers: {
"Connection": "keep-alive"
}
}, (err, response, body) => {
// do the things
});