'fetch' 方法是否提供与 'FileReader' 相同的功能?

Does 'fetch' method present the same functionality as 'FileReader'?

我设法逐字节读取文本文件,并将字符集从 windows-1251 更改为 Unicode,以便通过 input 元素和 FileReader。现在我想通过 fetch 对服务器中的文件执行相同的操作。有可能这样做吗? (fetch 将在通过 HTTP 提供的页面中,而 URL 将是相对的,例如 fetch("raw/graph_tab.txt") — 我并没有尝试直接从最终用户的机器读取文件,因为我有一个 input 字段和 FileReader).

工作代码块('windows-1251.js' 库由 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));            
            }};

如果你的意思是你想要 FileReader.readAsText(Blob, encoding) 方法的 encoding 参数,那么你会在 Content-Type [=31= 中设置一个 charset parameter ] 你的回应。

如果出于某种原因这不可行,那么您必须使用 Response object to a Blob using its Body.blob() 方法,然后将生成的 Blob 传递给 FileReader。

否则,不,即使 Response object 的方法与 FileReader 的方法相似,text() 方法不提供 encoding 选项...

您根本不必进行这种转换:您是 运行 一个网络服务器,它显然没有正确识别文件的编码。它应该在 Content-Type header 和 returns 中正确识别它(例如:Content-Type: text/plain; charset=windows-1251)。有关详细信息,请参阅 SO 自己的 Joel Spolsky 的 this article

如果您出于某种原因不能这样做:您可以将文件读取为二进制文件,并通过 fetch 响应中的 arrayBuffer 为其获取 ArrayBuffer

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
});

那么问题就是我们为...convert it here...做了什么。 :-) 您所指的库期望得到一个 "byte string",我猜这与您从 FileReaderreadAsBinaryString 方法中得到的相同。如果是这样,您可以将 ArrayBuffer 转换为这样的格式:

const str = new Uint8Array(buffer).map(byte => String.fromCharCode(byte)).join("");

所以:

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
});