与类似的问题(与从本地打开的.html文件在浏览器中运行的javascript有关)不同,我正在寻找一种解决方案,该解决方案在许多浏览器似乎已加强安全性并被接受后于2020年9月从公共网站访问时可以正常工作答案不再起作用。
我的用例是,我希望用户通过输入表单选择一个文件,然后向他们提供用于修改文件内容的选项,然后再将其上传到服务器(此时可能使用ajax)。
我意识到一种解决方法是将文件正常上传到服务器,在服务器上读取文件,将内容Ajax返回给用户,让他们对其进行修改,然后再将Ajax返回给服务器。我想保存一次往返,并在可能的情况下,第一次将文件内容直接读取到javascript变量中。
从类似的问题中我发现:
<input type="file" onchange="this.files[0].text().then(t => console.log(t))" />
,并且如果我从计算机(即file://
)打开.html网站,此方法有效,但是如果我从公共域(https://
)打开.html网站,则无效。
还有另一种方法可以在最新(2020年9月)Chrome / Firefox中运行吗?
答案 0 :(得分:0)
实际上这是可能的。
我已经放弃了。我确定我必须将文件上传到服务器,然后通过ajax将其发送回客户端,然后使用 用户,然后将其发送回服务器。
纯Javascript
不是。我找到了此链接:https://web.dev/read-files/ 描述以下方法:
<!-- Copyright 2018 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Read an image file</title>
<link rel="shortcut icon"
href="https://cdn.glitch.com/9b775a52-d700-4208-84e9-18578ee75266%2Ficon.jpeg?v=1585082912878">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<h1>
Read an image file
</h1>
<input type="file" id="file-selector">
<p id="status"></p>
<div>
<img id="output">
</div>
<script>
const status = document.getElementById('status');
const output = document.getElementById('output');
if (window.FileList && window.File && window.FileReader) {
document.getElementById('file-selector').addEventListener('change', event => {
output.src = '';
status.textContent = '';
const file = event.target.files[0];
if (!file.type) {
status.textContent = 'Error: The File.type property does not appear to be supported on this browser.';
return;
}
if (!file.type.match('image.*')) {
status.textContent = 'Error: The selected file does not appear to be an image.'
return;
}
const reader = new FileReader();
reader.addEventListener('load', event => {
output.src = event.target.result;
});
reader.readAsDataURL(file);
});
}
</script>
</body>
</html>
上面的代码将允许用户从高清中选择图像,然后使用FileReader API将数据加载到javascript中,而无需将其发送到服务器。我在其他地方读过FileReader不能在网络上工作,但是我错了。
如果您想读取其他类型的文件,请确保在FileReader上调用其他方法,例如为文本readAsText
或作为数组缓冲区readAsArrayBuffer
调用。
链接具有更多详细信息。
在Windows 10上于2020-10-02进行测试
反应
最简单的方法是使用react-dropzone
库https://github.com/react-dropzone/react-dropzone
来自官方文档(MIT)的以下内容:
import React, {useCallback} from 'react'
import {useDropzone} from 'react-dropzone'
function MyDropzone() {
const onDrop = useCallback((acceptedFiles) => {
acceptedFiles.forEach((file) => {
const reader = new FileReader()
reader.onabort = () => console.log('file reading was aborted')
reader.onerror = () => console.log('file reading has failed')
reader.onload = () => {
// Do whatever you want with the file contents
const binaryStr = reader.result
console.log(binaryStr)
}
reader.readAsArrayBuffer(file)
})
}, [])
const {getRootProps, getInputProps} = useDropzone({onDrop})
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
)
}