I managed to read the text file byte by byte and to change the charset from windows-1251 to Unicode for a file loaded from the end user's puter via an input
element and FileReader
. Now I want to do the same thing for a file from my server, via fetch
. Is it possible to do that? (The fetch
would be in a page served via HTTP and the URL would be relative, e.g. fetch("raw/graph_tab.txt")
— I'm not trying to read a file directly from the end user's machine as I was with an input
field and FileReader
).
Chunks of working code ('windows-1251.js' library is created by Mathias Bynens):
<input type="file" id="file"/>
<script type="text/javascript">
document.getElementById("file").addEventListener("change", readFile, false);
function readFile (evt) {
var files = evt.target.files;
var file = files[0];
var reader = new FileReader();
reader.onload = function(event) {
console.log(windows1251.decode(event.target.result));
}};
I managed to read the text file byte by byte and to change the charset from windows-1251 to Unicode for a file loaded from the end user's puter via an input
element and FileReader
. Now I want to do the same thing for a file from my server, via fetch
. Is it possible to do that? (The fetch
would be in a page served via HTTP and the URL would be relative, e.g. fetch("raw/graph_tab.txt")
— I'm not trying to read a file directly from the end user's machine as I was with an input
field and FileReader
).
Chunks of working code ('windows-1251.js' library is created by Mathias Bynens):
<input type="file" id="file"/>
<script type="text/javascript">
document.getElementById("file").addEventListener("change", readFile, false);
function readFile (evt) {
var files = evt.target.files;
var file = files[0];
var reader = new FileReader();
reader.onload = function(event) {
console.log(windows1251.decode(event.target.result));
}};
Share
Improve this question
edited Jan 7, 2019 at 11:42
T.J. Crowder
1.1m200 gold badges2k silver badges2k bronze badges
asked Jan 6, 2019 at 13:14
AndreyAndrey
739 bronze badges
6
- @T.J.Crowder thank for your explanation! May I ask for further clarification: you accented existing restrictions for one method 'FileReader'. I see it. But fetch method does not have such a restriction, it could read any source inserted manually in the code. So the question is about the ability of fetch method to proccess the binary fetched data in a way as it can make FileReader method. – Andrey Commented Jan 7, 2019 at 8:41
- @T.J.Crowder excuse my persistence, but I can't get the idea) Fetch method can take local path relative to default folder, you could see what I mean here stackoverflow./review/suggested-edits/21650814. Or I am wrong? – Andrey Commented Jan 7, 2019 at 8:55
- @T.J.Crowder I feel you're my last straw) I pletely get the idea now. But may I take the courage to repeat the question from the topic title? For my case the issue is that I perfectly process the binary data through FileReader but cannot understand how to get the same result by fetch method through web server... – Andrey Commented Jan 7, 2019 at 9:15
-
1
Do you have a non-
file://
URL to the file? I mean, once any relative URL has been resolved, does the absolute URL start withhttp://
orhttps://
? – T.J. Crowder Commented Jan 7, 2019 at 9:31 -
1
@T.J.Crowder Yes I do! Apache server is raised locally, java script code is executed on local index.html page.
fetch("raw/graph_tab.txt").then(function(response) {console.log(response.url);});
gives me localhost:8080/raw/graph_tab.txt in console. The target file is opened then normally when the link is clicked... – Andrey Commented Jan 7, 2019 at 11:18
2 Answers
Reset to default 3If you mean you want to have the encoding
parameter of the FileReader.readAsText(Blob, encoding)
method, then you'd set a charset
parameter in the Content-Type
header of your response.
If this is not doable for whatever reason, then you'd have to consume your Response object to a Blob using its Body.blob() method, and then pass the resulting Blob to a FileReader.
Otherwise, no, even though the Response object has similar methods than the ones of a FileReader, the text()
method doesn't provide an encoding option...
You shouldn't have to do this conversion at all: You're running a web server, which apparently isn't correctly identifying the encoding of the file. It should correctly identify it in the Content-Type
header it returns (e.g.: Content-Type: text/plain; charset=windows-1251
). See this article by SO's own Joel Spolsky for more information.
If you can't do that for some reason: You can read the file as binary and get an ArrayBuffer
for it via arrayBuffer
on the fetch
response:
fetch("raw/graph_tab.txt")
.then(response => {
if (!response.ok) {
throw new Error(response.status);
}
return response.arrayBuffer();
})
.then(buffer => {
// ...convert it here...
})
.catch(error => {
// Handle/report error
});
So then the question is what we do for ...convert it here...
. :-) The library you're referring to expects to get a "byte string" which I'm guessing is the same as what you'd get from the readAsBinaryString
method of FileReader
. If so, you can convert the ArrayBuffer
to that format like this:
const str = new Uint8Array(buffer).map(byte => String.fromCharCode(byte)).join("");
So:
fetch("raw/graph_tab.txt")
.then(response => {
if (!response.ok) {
throw new Error(response.status);
}
return response.arrayBuffer();
})
.then(buffer => {
const str = new Uint8Array(buffer).map(byte => String.fromCharCode(byte)).join("");
console.log(windows1251.decode(str));
})
.catch(error => {
// Handle/report error
});