Why is my downloaded file corrupted in Javascript? - javascript

I am trying to download a file from my nodeJS server, however opening the files afterwards is not possible. For example: The original 15kb JPG file will be 24kb when downloaded and impossible to show.
upload:
if (fs.existsSync(filePath)) {
res.download(filePath);
readStream.pipe(res);
} else {
return res.status(404).json({msg: "Failed to load file"});
}
download:
import fileDownload from "js-file-download";
const getFile = async (filename) => {
const headers = {
'responseType': 'blob',
'x-access-token': JSON.parse(localStorage.getItem('user')).token
}
await axios.post(getFileRoute, {
filename: filename
}, {headers: headers})
.then((response) => {
fileDownload(response.data, filename);
});
}
The picture preview is also shown in the network tab of google chrome's inspect. Thank you for your help!

Related

How do you user-inputted folders?

I'm wanting to allow users to select a folder(containing a .glb file) from their device, and then upload it to IPFS. The problem is that all documentation that I've seen for using a post method requires that you pass a local directory into the FormData (for example):
const pin = async (pinataApiKey, pinataSecretApiKey) => {
const url = `https://api.pinata.cloud/pinning/pinFileToIPFS`;
const src = "LOCAL/FILE/PATH";
var status = 0;
try {
const { dirs, files } = await rfs.read(src);
let data = new FormData();
for (const file of files) {
data.append(`file`, fs.createReadStream(file), {
filepath: basePathConverter(src, file),
});
}
return axios.post(url, data, {
maxBodyLength: "Infinity",
headers: {
"Content-Type": `multipart/form-data; boundary=${data._boundary}`,
pinata_api_key: pinataApiKey,
pinata_secret_api_key: pinataSecretApiKey,
},
});
} catch (error) {}
};
My question is, how do I get a user-inputted folder, then handle it so that it can be uploaded to Pinata IPFS through a POST method? I'm aware of <input type= "file" webkitdirectory>, but I'm not sure how to extract and "prep" the folder data for posting once a user has uploaded it. Any suggestions are welcome!

ZIP Archives downloaded from Next.js API route are corrupted

I am trying to implement the download of a ZIP archive from server using Next.js, axios and js-file-download. However, when I try to open the downloaded archive, an error pops up saying that the archive is corrupted.
I am positive that the archive on the server is valid, so the problem is in the transfer to the client.
Also, if I try to download another file type (for example a .txt file), it works.
This is the server code, in /pages/api/assignments/[assignmentId]/students/index.tsx:
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const assignmentId = req.query.assignmentId as string;
const assignment = // here I get assignment from database
switch(req.method) {
case('GET'):
const fileNames = assignment.fileUploads.map((fileUpload: AssignmentFileUpload) => fileUpload.fileName);
const archivePath = `./resources/assignment_archives/${assignmentId}.zip`;
// --- RELEVANT CODE STARTS HERE ---
const archiveReadStream = fs.createReadStream(archivePath);
res.writeHead(200, {
'Content-Type': 'application/zip',
'Content-Disposition': `attachment; filename=${assignment.title}.zip`
});
archiveReadStream.pipe(res);
}
}
And this is the code on the client side:
const handleDownload = async (event: any) => {
axios.get(`/api/assignments/${assignment.id}/students`, {
responseType: 'arraybuffer',
headers: {
'Content-Type': 'application/zip'
}
})
.then((res) => {
fileDownload(res.data, `${assignment.title}.zip`) // function imported from js-file-download
});
}
I have already tried fiddling with headers, but nothing worked.

File format not supported but when decoding it with base64 it works fine

Hello i'm having issue with uploading image to the cloud (Backblaze B2).
The problem is, when I use the example Thunder client to upload the file everything works fine and file is shown.
Now my problem is that when I upload with JS I don't know why it is corrupted or bugged.
Like when I upload an image and download it, Windows File Manager says : file format not supported.
I decoded the file with base64 img decoder and it works fine and image is shown.
const submitForm = () => {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e) {
// binary data
let imagedata = reader.result.slice(reader.result.indexOf(',') + 1)
console.log(imagedata);
console.log(sha1(imagedata));
const proxyurl = "https://cors-anywhere.herokuapp.com/";
let datadf = fetch(proxyurl + 'url', {
method: 'POST',
headers: {
"Accept": "*/*",
"User-Agent": "Thunder Client (https://www.thunderclient.io)",
"X-Bz-File-Name": file.name,
"X-Bz-Content-Sha1": "do_not_verify",
"Authorization": "auth",
"Content-Type": "b2/x-auto",
},
body: imagedata,
})
.then((response) => {
return response.json();
})
.catch((err) => {
return {
status: 'fail',
message: 'API CALL ERROR',
error: err.message
};
});
datadf.then(res => console.log(res))
};
reader.onerror = function(e) {
// error occurred
console.log('Error : ' + e.type);
};
.readAsDataURL() converts the file it reads into Base64, so it can be represented as a URL you can put into a browser. A very long URL, but still a URL.
If you store a Base 64 representation of an image into a file on your machine, then try to read it with an image-display program, the operation will fail: "This doesn't look like a .jpg, .png, or .gif" so I don't know what to do with it." That's what your Windows file manager error message means.
If you want the file's contents raw rather than Base64 encoded, you'll need to use .readAsArrayBuffer().

File is not showing local language after downloading

I have an application which is developed with node.js and hosted on heroku. We are generating a pdf on the node.js server and sending the stream to frontend, so that the users can download the file.
When i am trying it on the localhost, i am able to see proper content in the file. But when i host the node.js code on heroku and try the same, the file is not showing local language(telugu, an indian language) in the pdf. Below is the screenshot of the file i am getting.
The below code is the frontend code which will hit the server api and get the file content from server
const response = await axios.post(
'/reports/pdf',
{ tests: this.tests },
{ responseType: 'blob' },
);
window.console.log(response);
if (response) {
this.createAndDownloadBlobFile(response, 'tests');
}
The below code is to download the file. This function is called in the above code after getting the response.
createAndDownloadBlobFile(body, filename, extension = 'pdf') {
const blob = new Blob([body]);
const fileName = `${filename}.${extension}`;
if (navigator.msSaveBlob) {
// IE 10+
navigator.msSaveBlob(blob, fileName);
} else {
const link = document.createElement('a');
// Browsers that support HTML5 download attribute
if (link.download !== undefined) {
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', fileName);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
},
The node.js code is as below
return new Promise((resolve, reject) => {
pdf
.create(document, options)
.then((res) => {
var content = fs.readFileSync(path.resolve(__dirname, '../utils/output.pdf'));
resolve(content);
})
.catch((error) => {
reject(error);
});
});
I tried few different ways by changing the response format to base64 and changing the data format. But still no use. Any help would be really appreciated.

how to download an PDF from byteArraay in angular 6?

I am currently working in angular 6. i have to download pdf file from bytearray.
when i tried to download an pdf file. it downloads but when i open it. it shows error. please help me with it.
In the download.component.ts i am getting response as two values. first pdfname, second pdfbytearray. i am getting those values from component response.
sample response:
{
pdfName: "test.pdf",
pdfByteArray: "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC9Qcm9kdWNlcij"
}
download.service.ts:
generatePdf(id) {
const httpOptions = {
'responseType': 'arraybuffer' as 'json'
};
return this.http.post<any>(URL.BASE_URL + 'application/generate?id='+ id,
{ httpOptions },
);
}
download.component.ts:
import { saveAs } from 'file-saver/FileSaver';
generatePdf() {
this.downloadApiService.generatePdf('4')
.subscribe( pdf => {
console.log('pdf response: ', pdf);
var mediaType = 'application/pdf';
var blob = new Blob([pdf.pdfByteArray], {type: mediaType});
let fileName = pdf.pdfName;
saveAs(blob, fileName);
}, err => {
console.log('Pdf generated err: ', JSON.stringify(err));
});
}

Categories