I have a rest service made with node.js and express.js, that returns a zip trough response using express-zip:
res.zip([{path:'file', name: 'file'}]);
When i call it with node, to test it, with the following code, it creates a valid zip file:
var fs = require('fs');
var request = require('request');
request({
url: "http://deti-lei-2.ua.pt:3500/runProgram/posio/211/1",
method: "GET",
encoding: null,
headers: {
Authorization: 'token'
}
}).pipe(fs.createWriteStream('file.zip')).on('close', function () {
console.log('File written!');
});
But i need to use the service with angular 2, however, i tried many ways of doing the request and none worked, i always end up with a corrupt zip.
One of the ways i tried was the following:
downloadFile(program: string) {
var bytes = [];
for(var i = 0 ; i < program.length; i++){
bytes.push(program.charCodeAt(i));
}
var FileSaver = require('file-saver');
var blob = new Blob([bytes], {type:'application/zip'});
FileSaver.saveAs(blob,'Program');
}
I also tried creating a function in js with the code above, that was working, but i had no success because i could't use fs and request modules.
I appreciate if someone can help.
Related
I've tried almost every answer in relative questions, and couldn't find any solution to my case.
I'm new to Nuxt.JS, and I'm moving my project from Vue/CLI to Nuxt.js, now I'm stuck in sending POST request which contains images and data (FormData).
The FormData is appearing empty on the server side (Node.js)
The current working version of my code in Vue CLI:
const requestOptions = {
method: 'POST',
body: formData
};
return fetch(`/create`, requestOptions).then(handleResponse);
What I'm trying to achieve in Nuxt.JS (which is not working properly) by using nuxt/axios module:
methods: {
async sendRequest(){
let formData = new FormData();
formData.append('image',this.myFile);
formData.append('name',this.anyName);
var res = await this.$axios.$post('/create', formData);
}
}
EDIT: I tried to log the content before making the request like:
for (var pair of formData.entries()) {
console.log(pair[0]+ ' - ' + pair[1]);
}
And I can see the fields and values clearly as intended.
I've tried adding headers to the request:
this.$axios.$post('/create', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
But still getting: {} in Node.js while printing the request body.
What I'm doing wrong?
I am trying to upload a file using request module to Telegram's Bot API. However, I end up with a 502 Gateway Error. Here's my code:
var request = require("request");
var fs = require("fs");
fs.readFile("image.png",function(err,data){
var formdata = {};
formdata.chat_id = <chatid>;
formdata.photo = data;
if(err)
console.log(err);
request({
url : "https://api.telegram.org/bot<token>/sendPhoto",
method : "POST",
headers : {
"Content-Type" : "multipart/form-data"
},
formData : formdata
},function(err,res,body){
if(err)
console.log(err)
console.log(body);
})
});
Is this the proper way to upload a file or am I making a mistake somewhere?
I suggest, it's better for you to use form field of request object, which gives you possibility to send file using createReadStream function of fs module.For example:
var r = request.post({
url: url
},someHandler);
var form = r.form();
form.append('file',fs.createReadStream(filePath));
For proper use read:
https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options
https://github.com/request/request#forms
I have managed to do this without any problems before with Python and the Python SDK from Dropbox, but now that i am using Nodejs and the Dropbox HTTP API something goes wrong. When i save the PDF file locally i can only see parts of the original PDF, and when i compare it to the original file with for example WinMerge i see that the files are not equal and are different sized. The only difference i can think of is that it might be getting saved with a different encoding than the original, but i have tried most of them with iconv-lite and none of them gives a good result.
I also tried to use https://github.com/dropbox/dropbox-js to see if it gave a different result, and also https://www.npmjs.com/package/request instead of node-rest-client, but without success.
Has any one implemented this and made it work?
This is my code:
var fs = require('fs'),
RestClient = require('node-rest-client').Client;
var args = {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/pdf',
'Authorization': 'Bearer xxx'
}
};
var restClient = new RestClient();
var url = 'https://api-content.dropbox.com/1/files/auto/' + dropboxPath;
var filePath = '/var/temp/' + fileName;
restClient.get(url, arguments, function(body, response) {
fs.writeFile(filePath, response, function (error, written, buffer) {});
}
when testing with different encodings it looked something like this:
var fs = require('fs'),
RestClient = require('node-rest-client').Client,
iconvlite = require('iconv-lite');
iconvlite.extendNodeEncodings();
var args = {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/pdf',
'Authorization': 'Bearer xxx'
}
};
var restClient = new RestClient();
var url = 'https://api-content.dropbox.com/1/files/auto/' + dropboxPath;
var filePath = '/var/temp/' + fileName;
var options = { encoding: 'UTF-8' };
restClient.get(url, arguments, function(body, response) {
fs.writeFile(filePath, response, options, function (error, written, buffer) {});
}
I think node-rest-client always converts the returned data to a string, so it will end up corrupting binary data. See https://github.com/aacerox/node-rest-client/blob/master/lib/node-rest-client.js#L396.
The request library seems to have a similar issue when using a callback, but you can bypass that by piping directly to the file:
var fs = require('fs'),
request = require('request');
var accessToken = '123xyz456';
var filename = 'myfile.pdf';
request('https://api-content.dropbox.com/1/files/auto/' + filename, {
auth: { bearer: accessToken }
}).pipe(fs.createWriteStream(filename));
EDIT: I filed an issue on GitHub for the node-rest-client issue, and it looks like the library maintainer has already prepared a fix (in a branch). See https://github.com/aacerox/node-rest-client/issues/72.
I have to POST to an API that someone else has developed in order to obtain an authorization code, and as I have to do it in several different contexts I thought I'd move the code for handling the POST and getting the response to a service.
The frustrating thing at the moment is that I seem to be getting back the value that I want from the API, but can't return it from the server to the calling sails controller.
Here's the service source code:
module.exports = {
getVerifyCode: function(uuid, ip_addr) {
console.log (uuid);
console.log (ip_addr);
var http = require('http'),
querystring = require('querystring'),
// data to send
send_data = querystring.stringify({
uuid : uuid,
ip_addr : ip_addr
}),
// options for posting to api
options = {
host: sails.config.api.host,
port: sails.config.api.port,
path: '/verifyCode/update',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(send_data)
}
},
json_output = "",
// post request
post_req = http.request(options, function(post_res) {
post_res.on('data', function(chunk) {
json_output += chunk;
});
post_res.on('end', function() {
var json_data = JSON.parse(json_output),
verify_code = json_data.verify_code;
console.log("code="+verify_code);
return ('vc='+verify_code);
});
});
post_req.write(send_data);
post_req.end();
}
}
And here's two relevant lines from my controller action:
var vc = verify.getVerifyCode(req.session.uuid, req.connection.remoteAddress);
console.log('vc='+vc);
The weird thing is that the controller console log gets written before the service one does:
vc=undefined
code=YoAr3ofWRIFGpoi4cRRehP3eH+MHYo3EogvDNcrNDTc=
Any ideas? I have a much simpler service running (just some string manipulation stuff); I have a feeling the issue here relates to the asynchronous nature of the API request and response.
Jasper, your correct in your assumption that it is the " asynchronous nature of the API request and response".
When you execute your http call in your verify service, node makes that call and them moves on to the rest of the code console.log('vc='+vc); and does not wait for the http call to finish.
I'm not sure what your end result should be but you can rewrite your controller / service to include the callback (this is just one options, there are many ways to do this of course, other people should suggest others)
verify.js
getVerifyCode: function(uuid, ip_addr, cb) {
// Bunch of stuff
return post_req = http.request(options, cb(post_res});
}
then in your controller
controller.js
verify.getVerifyCode(req.session.uuid, req.connection.remoteAddress, function(resps){
// code in here to execute when http call is finished
})
I'm using version 2 of Box's API and attempting to upload files. I have Oauth 2 all working, but I'm having trouble making actual uploads.
I'm using Node.js and Express, along with the "request" module. My code looks something like this:
request.post({
url: 'https://upload.box.com/api/2.0/files/content',
headers: {
Authorization: 'Bearer ' + authToken
},
form: {
filename: ????,
parent_id: '0'
}
}, function (error, response, body) {
// ...
});
For now, I'm trying to upload to the root folder which, if I understand correctly, has an ID of '0'.
What I'm really not sure about is what value to give "filename". I don't have a true file to read from, but I do have a lengthy string representing the file contents I would like to upload.
How best should I upload this "file"?
For Box, I believe you want to use requests multi-part/form-data implementation.
It should look something like this:
var request = require('request');
var fs = require('fs');
var r = request.post(...);
var form = r.form();
form.append('filename', new Buffer("FILE CONTENTS"), {filename: 'file.txt'});
form.append('parent_id', 0);
var fs = require('fs');
var request = require('request');
var path = require('path');
function requestCallback(err, res, body) {
console.log(body);
}
var accessToken = 'SnJzV20iEUw1gexxxxvB5UcIdopHRrO4';
var parent_folder_id = '1497942606';
var r = request.post({
url: 'https://upload.box.com/api/2.0/files/content',
headers: { 'Authorization': 'Bearer ' + accessToken }
}, requestCallback);
var form = r.form();
form.append('folder_id', parent_folder_id);
form.append("filename", fs.createReadStream(path.join(__dirname, 'test.mp4')));