'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",我猜这与您从 FileReader
的 readAsBinaryString
方法中得到的相同。如果是这样,您可以将 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
});
我设法逐字节读取文本文件,并将字符集从 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",我猜这与您从 FileReader
的 readAsBinaryString
方法中得到的相同。如果是这样,您可以将 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
});