I created the following function to load a stream file. This stream is sent to the address specified with a POST. At the destination, I have another NodeJS service that with ExpressJS "capture" this POST but I have no idea how I can save the file to the destination.
NodeJS on my PC:
function sendFileToRaspberry(filePath) {
var options = {
method: 'POST',
url: 'http://x.x.x.x:8080/api/print',
qs: {file: fs.createReadStream(filePath)},
headers:
{
'cache-control': 'no-cache'
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
}
NodeJS on my Raspberry:
app.post('/api/print', function (req, res) {
ORIGINAL_IP = req.ip.replace("::ffff:", '');
console.log("Received a print request from: " + ORIGINAL_IP);
// Test history data for /api/printer API
var file = req.query.file;
console.log("Test data: " + file);
util.inspect(file);
});
But in the console log I get:
Received a print request from: y.y.y.y
Test data: [object Object]
How can I save this file on Rasp?
You can use a expressjs middleware helper like express-fileupload, multer.
I think, you have use Multipart Form Uploads to upload a file via http POST.
Client side (Your PC)
function sendFileToRaspberry(filePath) {
var options = {
method: 'POST',
url: 'http://x.x.x.x:8080/api/print',
formData: {
file: fs.createReadStream(filePath)
},
headers: {
'cache-control': 'no-cache'
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
}
Related
My server will post data to another server, is there any way that I can add logger and log the response and request data thanks
const request = require('request');
requestIotPlatform = function requestIotPlatform(req, res, next) {
var formData = JSON.stringify(req.body);
var form = {
data_in: formData
};
var uri = 'XXXXXXXXXXXXXXXXXXXXXX';
var headers = {
'Authorization': authBase64,
//'Content-Length': form.length,
'Content-Type': 'application/x-www-form-urlencoded',
'Connection': 'keep-alive',
'charset': 'utf-8'
};
request.post({
headers: headers,
uri: uri,
form: form
}, function (err, response, body) {
console.log(response.statusCode)
});
next();
}
module.exports = { requestIotPlatform };
I use this module, basically it's a middleware for logging request/responses in Express apps: https://www.npmjs.com/package/express-requests-logger
In an Azure Function as a backend for my webpage, I requested an Azure AD publisher's authorization token as per this page instructed.
This is the line of codes of my Azure Functions:
// Stringfy request body
const postData = querystring.stringify({
'grant_type': 'client_credentials',
'client_id': client_id,
'client_secret': client_secret,
'resource': resource,
});
// Initiate options
var httpAgent = new http.Agent();
httpAgent.maxSockets = 200;
const options = {
hostname: 'login.microsoftonline.com',
path: `/${tenantId}/oauth2/token`,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
agent: httpAgent,
}
const tokenReq = http.request(options, (res) => {
console.log(`STATUS: ${res.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
res.setEncoding('utf-8')
res.on('data', (chunk) => {
console.log(chunk);
body += chunk;
});
res.on('end', () => {
console.log('No more data in response.');
console.log("body:" + body);
context.res = {
status: 200,
body: body,
};
});
});
tokenReq.on('error', (e) => {
console.log(`problem with request: ${e.message}`);
context.res = {
status: 500,
body: `problem with request: ${e.message}`,
}
});
// write data to request body
tokenReq.write(postData);
tokenReq.end();
The expected response was the access token that I require, however running it locally I got STATUS 302, and a header containing a location and some other parameters, as a response. In my understanding STATUS 302 states that the URL is moved temporarily to the location provided in the header. Now, I don't know what I'm supposed to do, the request that I have to make is supposed to be a POST request so a redirection would not work. I've also tried to make a new request after receiving the redirect URL, but I got an error message saying: getaddrinfo ENOTFOUND {redirect URL from header}. What did I do wrong here?
The 302 error was caused by http module, you use require('http'); and http.request(options, (res).... to do the request, so it shows 302 error.
I suggest you to use var request = require('request'); to do the request, below is my function code for your reference (before use request module, you need to run npm install request to install it first):
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
var result = await generatetoken(context);
context.res = {
body: result
};
}
function generatetoken(context){
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://login.microsoftonline.com/<your tenant id>/oauth2/token',
'headers': {
'Content-Type': 'application/x-www-url-form-urlencoded'
},
form: {
'client_id': 'xxxxxx',
'grant_type': 'client_credentials',
'resource': 'xxxxx',
'client_secret': 'xxxxx'
}
};
return new Promise(function(resolve, reject) {
request(options, function(err, res) {
if (err) {
reject(err);
} else {
context.log(res.body);
resolve(res.body);
}
})
})
}
I'm using a platform for data security, and they have this code snippet showing how to post data to their platform:
They're using the request module: https://github.com/mikeal/request
const request = require('request');
request({
url: 'https://mypass.testproxy.com/post',
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({'secret' : 'secret_value'})
}, function(error, response, body){
if(error) {
console.log(error);
} else {
console.log('Status:', response.statusCode);
console.log(JSON.parse(body));
}
});
It works fine, but I wanted to replace the 'secret' : 'secret_value' object with my form data, but I'm having a hard time figuring out how to do this.
The only way I know how to retrieve form data is with req.body:
function(req, res) {
var form = {
card_number: req.body.card_number,
card_cvv: req.body.cvv,
card_expirationDate: req.body.card_expirationDate,
};
// ...
});
How would I do that? Any help is greatly appreciated.
I know the code below is wrong, but that's the idea of what I want to achieve:
request( function(req, res) {
var form = {
card_number: req.body.card_number,
card_cvv: req.body.cvv,
card_expirationDate: req.body.card_expirationDate,
};{
url: 'https://mypass.testproxy.com/post',
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(form)
...```
The form data will be sent with the content type application/x-www-form-urlencoded e.g. card_number=123&cvv=456.
Express has a middleware to parse that https://expressjs.com/en/api.html#express.urlencoded
app.use(express.urlencoded());
The parsed values will be in req.body in your post route. So e.g. req.body.card_number will contain the value 123.
You can put the request inside the route:
app.post('/', function (req, res) {
var form = { /* ... */ }
request({
body: JSON.stringify(form),
/* ... */
})
})
I am struggling to get the access token of the user on LINE oauth2, everything works fine as I can redirect the user to callback URL and generate code in the URL, I've also managed to work it in POSTMAN but in my code, it throws an error
"Invalid request, some parameters are invalid or missing".
Any help is appreciated. Thank you.
Here is my code.
var queryCode;
app.get("/profile", function (req, res, next) {
console.log('Request Type:', req.query.code);
queryCode = req.query.code;
console.log(typeof queryCode);
res.render('pages/profile', { code: req.query.code });
var data = {
grant_type: "authorization_code",
code: queryCode,
redirect_uri: "https://mydemosampleonlywebsite.com/profile", // not real edited
client_id: 2, // edited for security
client_secret: "98" // edited for security
}
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log('body ' + body);
}else{
console.log('err ' + body);
}
}
var options = {
method: 'POST',
url: 'https://api.line.me/oauth2/v2.1/token',
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
},
body: JSON.stringify(data)
}
request.post(options, callback);
res.end();
});
I've managed to solved it using form property instead of body in my options object.
var options = {
method: 'POST',
url: 'https://api.line.me/oauth2/v2.1/token',
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
},
**form: data**
}
When I try to log the data that was received by the server it is displayed as one long string. Instead I would like the received data to be seperable as different variables.
Client code
function sendData() {
var datas = { testdata: "TEST", testdata2: "TEST2" };
$.ajax({
url: 'server',
data: JSON.stringify(datas),
type: 'POST',
success: function (data) {
$('#lblResponse').html(data);
},
error: function (xhr, status, error) {
console.log('Error: ' + error.message);
$('#lblResponse').html('Error connecting to the server.');
}
});
}
Server code
var http = require('http');
http.createServer(function (req, res) {
console.log('Request received');
res.writeHead(200, {
'Content-Type': 'text/plain',
'Access-Control-Allow-Origin': '*'
});
req.on('data', function (chunk) {
console.log('GOT DATA!');
var receivedData = JSON.parse(chunk);
console.log(receivedData);
});
res.end("hello");
}).listen(1337);
I would like to be able to call for a single variable to get the value from it in the server. For example console.log(testdata); should display the value "TEST".
By stringifying your data object, you're sending a string to the server as the request body, and it's probably encoded using the "application/x-www-form-urlencoded" encoding.
You probably shouldn't JSON.stringify(datas), just use datas.
You need to parse the request body on the server. For that you could use a module like body