I have a problem (or maybe two) with saving files using the HTML5 API files.
Files come from the server as a byte array, and I need to save it. I tried several methods described in SO:
- create blob and open it in a new tab
- creating a hidden asor tag with "data:" in the href attribute
- using fileSaver.js
All approaches allow you to save the file, but break it by changing the encoding to UTF-8, and the file (in the current test case) is in ANSI. And it seems that I have problems: on the server side and on the client side.
Server side: The server side is an ASP.NET Web API 2 application whose controller sends the file using HttpResponseMessage with StreamContent. ContentType is correct and matches the actual file type.
But as you can see in the screenshot below, the server response (data.length) is smaller than the actual file size calculated at boot (file.size). You can also see here that the HTML5 File object has another size (f.size).

If I add a CharSet with the value βANSIβ to the ContentType message of the server response property, the file data will be the same as when loading, but when saving the result file, they still have the wrong size and will be violated:

Client side: I tried to set the encoding using the parameters of the JS file, but this did not help. As you can find here and here, Eli Gray, author of FileUplaod.js, says that
The encoding / encoding in a type is just the metadata for the browser, not the encoding directive.
which means if I understood correctly that it is impossible to change the encoding of the file.
Result of the problem : in the end, I can successfully upload files that cannot be opened. 
I have two questions:
- How to save a file "as is" using the File API. Currently, I canβt use a simple way with a direct link and the βuploadβ attribute due to serveride checking for access_token in the request header. Maybe this is the bottleneck problem?
- How can I avoid installing CharSet from the server side and also send an array of bytes "as is"? Although this problem can be cracked in some way, I think it is more important. For example, while the "ANSI" charset solves the problem with the current file, WinMerge shows that it is encoded in the Cyrillic alphabet "Windows-1251", and it can also be any other.
PS The problem is associated with all types of files (extensions), except * .txt.
Update
Server Side Code:
public HttpResponseMessage DownloadAttachment(Guid fileId) { var stream = GetFileStream(fileId); var message = new HttpResponseMessage(HttpStatusCode.OK); message.Content = new StreamContent(stream); message.Content.Headers.ContentLength = file.Size; message.Content.Headers.ContentType = new MediaTypeHeaderValue(file.ContentType) { // without this charset files sent with bigger size // than they are as shown on image 1 CharSet = "ANSI" }; message.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = file.FileName + file.Extension, Size = file.Size }; return message; }
Client Code (TypeScript):
private downloadFile(file: Models.File) { var self = this; this.$service.downloadAttachment(this.entityId, file.fileId).then(
My code is almost the same as in the answers to related questions on SO: instead of setting a direct link in the 'a' tag, I process a click on it and upload the contents of the file via XHR (in my case using the Angularjs $ http service), Having received the contents of the file, I create a Blob object (in my case, I use the File class, which comes from Blob), and then try to save it using FileSaver.js. I also tried the Blob encoded URL approach in the href attribute, but it only opens a new tab with the file broken in the same way. I found that probem is in the Blob class - by calling it a constructor with "normal" file data, I get an instance with the "wrong" size, as seen in the first two sessions. So, as far as I understand, my problem is not how I try to save the file, but how I create it - File API