最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Does 'fetch' method present the same functionality as 'FileReader'? - Stack Overflo

programmeradmin3浏览0评论

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 with http:// or https://? – 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
 |  Show 1 more ment

2 Answers 2

Reset to default 3

If 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
});
发布评论

评论列表(0)

  1. 暂无评论