npm azure-storage download file as base64 - node.js

I am using this package to download the file from azure to local node server. But I do not want to save the file in local server and then read it to convert to base64, I want to directly convert it to base64. How can I achieve this?
this.blobService.getBlobToStream('pictures', path, fs.createWriteStream(`./src/temp/${filename}.jpeg`), function(error, result, response) {
if (!error) {
resolve({ message: `Items in container pictures:`, data: result});
} else {
reject(error);
}
});

Built-in Node only supports ecnode Buffer type to base64, since you don't want to download blob to local server, you have to use external module to encode stream.
npm install base64-stream then use code below.
var base64 = require('base64-stream');
...
this.blobService.createReadStream(container, path).pipe(base64.encode()).pipe(res);
Notice that in your later question, you specify Content-Type using
res.header('Content-Type', properties['contentType']);
Content-Type setting should be omitted. In my test, if set Content-Type successfully, the image will be downloaded as attachment instead of being displayed as inline content. Your code succeeds because it actually sets Content-Type to undefined.
Properties you use is a BlobResult(Json format)with blob info
BlobResult {
container: xxx,
...
contentSettings:
{ contentType: 'image/jpg',
contentMD5: 'uNkt2WJ75X13TjQbfY7qkA==' },
...
}
So contentType should be used in this format properties.contentSettings.contentType

Related

Can't view image that downloaded and saved to local files from s3 using aws sdk node js

I'm using node js aws-sdk package to download files from s3 storage, and when I download jpeg image and save it as a local file I can't view it. Is it the right way to download jpeg image?
public async downloadFile(fileName: string, targetPath: string): Promise<void> {
try {
const awsObject = await this.s3
.getObject({
Bucket: BUCKET,
Key: fileName,
})
.promise();
fs.writeFileSync(targetPath, awsObject.Body.toString());
} catch (error) {
throw new Error(`Failed to download file from aws storage with error ${error}`);
}
}
this is how I call it:
await awsSdk.downloadFile('fileInS3.jpeg', `test.jpeg`);
When I try to open the saved file I receive an error that says
The file “test.jpeg” could not be opened. It may be damaged or use a file format that Preview doesn’t recognize.
Update
Solved by replacing
fs.writeFileSync(targetPath, awsObject.Body.toString());
With
fs.writeFileSync(targetPath, awsObject.Body as Buffer);
This looks like a problem:
awsObject.Body.toString()
If you're writing an image, converting it to a string is going to break it.

Saving image in local file system using node.js

I was working on a simple code to download missing images from a site and save it in the local system, given its complete URL. I am able to get the data in binary format as response and also I am able to save it properly. But when I try to open the image it shows the format is not supported by the system. I tried to save some js and css file and they are being saved properly and I am able to view them as well. But I am having problem with all the image formats.
Here is the code I wrote:
try {
response = await axios.get(domain + pathOfFile);
console.log(response);
fs.writeFile(localBasePath + pathOfFile, response.data, "binary", (error) => {
if (error) console.log("error while writting file", error.message);
});
} catch (error) {
console.log("error in getting response", error.message);
}
domian: contains the base domain of the site
pathOfFile: contains the path of file on that domain
localBasePath: the base folder where I need to store the image
I even tried to store the response in a buffer and then tried to save the image, but still I am facing the same problem.
Any suggestions would be appreciated.
You need to define responseEncoding while calling axios.get method.
Change your line to:
response = await axios.get(domain + pathOfFile, {responseEncoding: "binary"});

Angular7 httpclient get call unable to parse PDF as blob

Angular7 Httpclient GET request not allowing to set {responsetype: 'application/pdf'} I tried combinations of blob,bytearray etc.
Its treating as JSON and failing on JSON.parse
I tried diff combinations as arraybuffer, blob
let requestOptions: Object = {
/* angualr 7 is not allowing this for some reason */
responseType: 'application/pdf'
}
/* not working */
return this.http.get<any>(this.streamURL , requestOptions);
Please i need a way out to read the response as PDF instead as JSON.

Successfully Saving base64 Image to Azure Blob storage but blob image always broken/small white box

I have a image converted to base64 I am trying to upload to my azure blob storage using createBlockBlobFromText.
self.blobServer.createBlockBlobFromText(containerName, fileName, baseStrChars, { contentSettings: { contentType: 'image/jpeg' } }, function(error, result, response) {
if (error) {
console.log(error);
}
console.log("result", result);
console.log("response", response);
});
My new jpeg image appears in blob storage container but when I go to the blob image URL I always get this.
My container's access policy is set to container and I pasted my base64 string to a base64 to image converter and the correct image appears. The problem seems to be the way I create the blob and not the base64 string.
I am puzzled as to why the whole flow seems to be working, but still the image is broken when I go to the URL. Any ideas ?
To visit the images directly via Urls in browser requires binary content. You can convert the base64 encoded string to binary buffer in your node.js backend, and upload the buffer string to Azure Storage.
Please try the following code snippet:
var rawdata = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
var matches = rawdata.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
var type = matches[1];
var buffer = new Buffer(matches[2], 'base64');
blobsrv.createBlockBlobFromText('mycontainer','profile-pic-123.jpg', buffer, {contentType:type}, function(error, result, response) {
if (error) {
console.log(error);
}else{
console.log(result)
}
});

Error when downloading a file with Meteor from Github assets API

I'm stuck with a bug in my Meteor application. What I'm trying to do is to get a release asset file from github, and unzip it. I was able to download it from a standard browser.
The result from my Meteor request contain a Buffer, that I'm able to save to a binary if I want to, but is different from the binary I got from my browser ( I compared the hex code for each files, and even the size is different).
When I'm trying to open the archive file downloaded through Meteor (with windows zip program or with JSZip) It tells me that the file is corrupted.
Here is the code I used to download the file :
HTTP.call('GET',asset.url,{ // asset.url is a valid one
params:{
'access_token':token
},
headers: {
'Accept':"application/octet-stream",
'User-Agent':"My app",
}
},function( error, result ) {
if(error)console.log(error);
else{
console.log('file downloaded !');
var app_archive = new JSZip(); // I'm using JSZip for decompressing the stream
app_archive.load(new Buffer(result)); // fail here
package_file = app_archive.file('package.json');
console.log(package_file);
}
});
and here is the Meteor console output :
=> Meteor server restarted
I20160313-16:56:43.975(-5)? file created !
I20160313-16:56:44.105(-5)? Exception in callback of async function: Error: Corr
upted zip : can't find end of central directory
I20160313-16:56:44.106(-5)? at Object.ZipEntries.readEndOfCentral (C:\Users\
jimmy\AppData\Local\.meteor\packages\udondan_jszip\2.4.0_1\npm\node_modules\jszi
p\lib\zipEntries.js:135:19)
I20160313-16:56:44.108(-5)? at Object.ZipEntries.load (C:\Users\jimmy\AppDat
a\Local\.meteor\packages\udondan_jszip\2.4.0_1\npm\node_modules\jszip\lib\zipEnt
ries.js:197:14)
I20160313-16:56:44.114(-5)? at Object.ZipEntries (C:\Users\jimmy\AppData\Loc
al\.meteor\packages\udondan_jszip\2.4.0_1\npm\node_modules\jszip\lib\zipEntries.
js:21:14)
I20160313-16:56:44.116(-5)? at Object.module.exports [as load] (C:\Users\jim
my\AppData\Local\.meteor\packages\udondan_jszip\2.4.0_1\npm\node_modules\jszip\l
ib\load.js:11:18)
I20160313-16:56:44.117(-5)? at server/FabMo-App-Store.js:122:19
I20160313-16:56:44.119(-5)? at runWithEnvironment (packages/meteor/dynamics_
nodejs.js:110:1)
I think It may be related to an encoding issue, but I tried almost every encoding format without any success. I'm open to any suggestion.
You're right, this is an encoding issue. From the documentation, you get in the result the body of the HTTP response as a string. To get the content as string, you/the browser/the framework will need to decode it from its binary form using its encoding (UTF8 usually). You try to get a binary file, "decoding" it will corrupt it.
You need to get the result in a binary format. The issue #1670 looked promising but wasn't merged. Using meteor add http aldeed:http, I get
HTTP.call('GET',asset.url,{
params:{
responseType: "arraybuffer"
// ...
},
// ...
},function( error, result ) {
var app_archive = new JSZip();
app_archive.load(result); // result is an ArrayBuffer
});
Finally made it working by using the request package
Here is the code :
request({
method : "GET",
url : asset.url,
headers:{
'Accept':"application/octet-stream",
'User-Agent':"My App",
'token':token
},
encoding: null // <- this one is important !
}, function (error, response, body) {
if(error || response.statusCode !== 200) {
// handle error
}
var app_archive = new JSZip();
app_archive.load(body);
package_file = app_archive.file('package.json').asText();
console.log(package_file);
});

Resources