File not opening after download: ReactJs + Spring Boot - javascript

I am developing a web application and one of my use cases is for users to have the ability to upload and download files from the server. I'm using ReactJs and Spring Boot.
Front-End code:
downloadFileClicked(id, fileName, fileType){
TestDataService.downloadFile(id)
.then(response=>{
console.log(response)
const file = new Blob(
[response.data],
{type: fileType}
)
let url = window.URL.createObjectURL(file)
let a = document.createElement('a')
a.href=url
a.download= fileName
a.click()
})
}
Back-End code:
#GetMapping("/downloadFile/{fileId:.+}")
public ResponseEntity<Resource> downloadFile(#PathVariable Long fileId, HttpServletRequest request ){
//Load file as a resource
DatabaseFile databaseFile = fileStorageService.getFile(fileId);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(databaseFile.getFileType()))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""+databaseFile.getFileName()+"\"")
.body(new ByteArrayResource(databaseFile.getData()));
}
When the user clicks download - the file does indeed download and seemingly in the correct format but when each application tries to open the file I am faced with such errors as the file format is not supported or the file is corrupt.
The file data is being stored as a byte array in a MySQL database. I have tried a number of different methods to download the file but I have encountered the same error each time. Any help would be greatly appreciated!

Related

Upload password protected file to server

I am running a Python HTTP server that host a captive portal. Basically I'm trying to upload a password protected file to the server.
Right now I am able to upload files to the server with JavaScript and FileReader. This is how I do it:
var file_cli_cert = document.getElementById(id="exa_cli_cert").files[0];
const xmlhttp1 = new XMLHttpRequest();
let name = file_cert.name;
let reader = new FileReader();
reader.readAsText(file_cert);
xmlhttp1.open("POST", '/load/cert');
reader.onload = function(){
xmlhttp1.send(name +"&CERT="+reader.result);
With non-password protected files this works well.
For password protected files my idea is to get the file and the password to access to the data. The problem is that I don't know how to access to password protected files in JS and i think it's not possible. So right now i am wondering how to send the file and the password to the server and access the file data there.
If I send the file object with XMLHttpRequest.send(), on the server side I get the object in string format.
To read the POST message, in the server side, I do:
ctype, pdict = cgi.parse_header(self.headers['content-type'])
content_len = int(self.headers.get('Content-length'))
post_body = self.rfile.read(content_len) #read credentials
self.send_response(201)
self.end_headers()
if self.path.endswith('/load/cert'): #if user loads a certificate
post_body = post_body.decode()
post_body = post_body.split("&CERT=") #split name and file content
name_cert = post_body[0]
file_content = post_body[1]
f = open("./certs/"+name_cert, "w")
f.write(file_content)
f.close()
I'm a newbie at this and I have been looking for a solution for hours. Any help will be appreciated.
No python expert but reading a encrypted file as Text with FileReader could be problematic as it could lead to some data loss when encoding it as text. You should rather be reading it as binary using reader.readAsArrayBuffer()
But there is no need to read the content of the file into memory and allocate memory, just upload the blob/file directly to the server and it will take care of sending the data from the disc to the network without touching the main javascript thread without any text transformation.
const [ file ] = document.querySelector('#exa_cli_cert').files
fetch('/load/cert', {
method: 'POST',
body: file,
headers: {
'x-file-name': file.name
}
})
.then(r => r.arrayBuffer())

Download .msg files in client side Reactjs

I have a server containing multiple .msg files
I want to enable the user to download them in the client side using the following code:
const download = (fileName) => {
var FileSaver = require('file-saver');
FileSaver.saveAs(constants.filesUploadUrl + fileName, fileName);
}
The download is working fine with all data types except .msg files
It gives me "Failed - No file"
Is there a way to enable downloading .msg files in client side?
It turned out that I needed to convert the content type into "application/vnd.ms-outlook"
As it wasn't recognized via Google chrome as .msg
My backend ASP.Net Core
Code for mapping MIME Type:
}
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".msg"] = "application/vnd.ms-outlook";
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
ContentTypeProvider = provider
});

Upload a File from Local Angular Folder to Server

I Have placed four static files in Assets/Image Folder in my Angular 8 app.
User has provision to select one File.
My problem is that, I want to upload the selected file to the server in his own Server Folder.
I tried this
var File = new file( new File(["img1"],"./assets/images/nathure_image1.png");
and send this file to server
public uploadImage(fileToUpload: File): Observable<any> {
const formData: FormData = new FormData();
formData.append('fileKey', fileToUpload, fileToUpload.name);
return this.http.post(this.appSettings.API_Config + this.controllerName + '/uploadImage', formData);
}
but it is wrong it create new file and not sends already existing File
Please let me know if my question is unclear ,
I can help with more details
I just want to send my existing client file to serve through API
Thanks for any help

Is there a way to download any kind of file using angular filesaver?

I'm using node.js and angular.js for my app and I'm trying to download files through the browser using Blob and fileSaver.js.
I've used these in other sections of my app to download text files and pdf files specifying the correct type when creating the Blob object without any problem, but in the current section I need to support any type of file and I don't know if it's possible.
For example, I've tried downloading an image file with and without type:image/png and the result was a corrupted image - inspecting it in a text editor and comparing it with the original file shows that many of the bytes were changed.
Here are the code snippets I use:
Server:
fs.readFile(/* snipped file path */, function(err, data){
if(err){
/* handle error */
}
else{
res.send(data);
}
});
Client:
$http.get(/* endPoint URL */)
.success(function(result){
var data = new Blob([result], {type: 'image/png'});
FileSaver.saveAs(data, filename);
});
A few questions:
Do I need to specify type for Blob? If so, do I need to specify it at server, too (it's a pain to determine it)? Can't I just skip it on both ends?
What causes the image test to result in corrupted file? Am I missing some content-type header or something?
Try adding {contentType: 'arraybuffer'} to your GET request and remove type from Blob definition, like so:
$http.get(/* endPoint URL */, {contentType: 'arraybuffer'})
.success(function(result){
var data = new Blob([result]);
FileSaver.saveAs(data, filename);
});
(Edit: deleted redundant type definition from Blob)

Excel downloaded using window.saveAs() is not opening

I'm developing and application that has node.js at backend and Angular.js in front end. I'm using exceljs module in node to create a xlsx book. UI is making ajax call to download xlsx file.
Node.js code.
response.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
response.setHeader("Content-Disposition", "attachment; filename=" + quoteId +".xlsx");
workbook.xlsx.write(response).then(function () {
response.end();
});
Angular code
DownloadService.downloadServiceCall(inputParam).then(
function success(res){
var blob = new Blob([res.data], { type: res.headers()['content-type'] });
var header = res.headers()['content-disposition'];
var fileName = header.match(/filename=(.+)/)[1];
window.saveAs(blob,fileName);
});
I'm able to download csv file and open it with above code.
Excel file is getting downloaded but I'm unable to open the same. It throws following error
Anyone have an idea about this issue, please suggest the solution. Any help on this would be appreciated.
Thanks..
It was due to async call from Angular. Has nothing to do with saveAs. Added responseType:'arraybuffer' in the request object. It resolved the issue.
$http({method:'get',url:'',responseType:'arraybuffer'})

Categories