遍历多个图像数组以单独上传到 AWS s3 ReactJS
Loop through array of multiple images to upload individually to AWS s3 ReactJS
我正在构建一个上传页面,该页面应该拍摄多张图像并使用 AWS 放大存储将它们上传到 aws s3。
我有一些问题
上传前我需要将所有图片编码为base64格式
它一次只允许上传一张图片,所以我需要遍历文件数组并逐个上传。
我无法使用 file.name
获取文件名。
我应该如何遍历图像数组files
将它们编码为 base64,然后单独上传?
以下代码一次上传一张图片,但文件名未定义。
const file = useRef(null);
function handleFileChange(event) {
file.current = btoa(event.target.files);
console.log(event.target.files) ///// length: 7
/// 0: File {name: "921 crest road (19 of 91).jpg", lastModified: 1579836842179, lastModifiedDate: Thu Jan 23 2020 22:34:02 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 13998488, …}
/// 1: File {name: "921 crest road (20 of 91).jpg", lastModified: 1579836859659, lastModifiedDate: Thu Jan 23 2020 22:34:19 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 14433420, …}
/// 2: File {name: "921 crest road (21 of 91).jpg", lastModified: 1579836860868, lastModifiedDate: Thu Jan 23 2020 22:34:20 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 14524865, …}
/// 3: File {name: "921 crest road (22 of 91).jpg", lastModified: 1579836861497, lastModifiedDate: Thu Jan 23 2020 22:34:21 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 13995939, …}
/// 4: File {name: "921 crest road (23 of 91).jpg", lastModified: 1579836884687, lastModifiedDate: Thu Jan 23 2020 22:34:44 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 13982365, …}
/// 5: File {name: "921 crest road (24 of 91).jpg", lastModified: 1579836885360, lastModifiedDate: Thu Jan 23 2020 22:34:45 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 14288288, …}
/// 6: File {name: "921 crest road (25 of 91).jpg", lastModified: 1579836886846, lastMod
console.log(file.current) //// undefined
}
async function handleSubmit(event) {
event.preventDefault();
setShowLoading(true);
try {
console.log(file.name) ///undefined
const filename = `${job.jobId}---${file.name}`;
const stored = await Storage.put(filename, file.current, {
contentType: file.type
});
} catch (e) {
alert(e);
console.log(e.message)
}
setShowLoading(false);
}
var centerText = {textAlign: "center"}
return(
<IonPage>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton/>
</IonButtons>
<IonTitle>Upload Images</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding">
<form onSubmit={handleSubmit}>
<input multiple="true" type="file" onChange={(e) => handleFileChange(e)}></input>
<IonButton expand="block" color="primary" strong="true" size="default" type="submit" >Upload</IonButton>
</form>
</IonContent>
</IonPage>
);
}
export default withRouter(JobInfo);
已更新代码 -- 仍然无法正常工作!
const file = useRef(null);
function extractInfo(file) {
console.log(file)
return {
name: file.name,
type: file.type,
content: btoa(file.content),
};
}
async function handleFileChange(event) {
file.current = event.target.files;
}
async function handleSubmit(event) {
const result = await Promise.all(
file.current.files
.map(extractInfo)
.map(uploadFile)
);
console.log(file.files)
}
async function uploadFile(file) {
setShowLoading(true);
try {
const filename = `${job.jobId}-${file.name}`;
const stored = await Storage.put(filename, file.current, {
contentType: file.type
});
} catch (e) {
alert(e);
console.log(e.message)
}
setShowLoading(false);
}
var centerText = {textAlign: "center"}
return(
<IonPage>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton/>
</IonButtons>
<IonTitle>Upload Images</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding">
<form onSubmit={handleSubmit}>
<input multiple type="file" ref={file} onChange={(e) => handleFileChange(e)}></input></input>
<IonButton expand="block" color="primary" strong="true" size="default" type="submit" >Upload</IonButton>
</form>
</IonContent>
</IonPage>
);
}
export default withRouter(JobInfo);
您忘记在输入元素中使用 ref。
使用 Promise.all 链接所有的承诺。
所以你的问题可以通过这样的方式解决:
const { useState, useRef } = React;
function Uploader() {
const file = useRef({});
function readContent(file) {
return new Promise((accept, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => accept({
name: file.name,
type: file.type,
content: reader.result
});
reader.onerror = () => reject();
});
}
function upload(file) { // fake upload
return new Promise(accept => {
setTimeout(() => accept(file), 1000);
});
}
function onSubmit(event) {
event.preventDefault();
const filesAsArray = [...file.current.files];
const fileInfo = Promise.all(filesAsArray.map(readContent))
.then(files => Promise.all(files.map(upload)))
.then(console.log);
return false;
}
return (
<div>
<form onSubmit={onSubmit}>
<input ref={file} type="file" multiple={true} />
<input type="submit" value="Upload" />
</form>
</div>
);
}
ReactDOM.render(<Uploader />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
我正在构建一个上传页面,该页面应该拍摄多张图像并使用 AWS 放大存储将它们上传到 aws s3。
我有一些问题
上传前我需要将所有图片编码为base64格式
它一次只允许上传一张图片,所以我需要遍历文件数组并逐个上传。
我无法使用
file.name
获取文件名。
我应该如何遍历图像数组files
将它们编码为 base64,然后单独上传?
以下代码一次上传一张图片,但文件名未定义。
const file = useRef(null);
function handleFileChange(event) {
file.current = btoa(event.target.files);
console.log(event.target.files) ///// length: 7
/// 0: File {name: "921 crest road (19 of 91).jpg", lastModified: 1579836842179, lastModifiedDate: Thu Jan 23 2020 22:34:02 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 13998488, …}
/// 1: File {name: "921 crest road (20 of 91).jpg", lastModified: 1579836859659, lastModifiedDate: Thu Jan 23 2020 22:34:19 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 14433420, …}
/// 2: File {name: "921 crest road (21 of 91).jpg", lastModified: 1579836860868, lastModifiedDate: Thu Jan 23 2020 22:34:20 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 14524865, …}
/// 3: File {name: "921 crest road (22 of 91).jpg", lastModified: 1579836861497, lastModifiedDate: Thu Jan 23 2020 22:34:21 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 13995939, …}
/// 4: File {name: "921 crest road (23 of 91).jpg", lastModified: 1579836884687, lastModifiedDate: Thu Jan 23 2020 22:34:44 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 13982365, …}
/// 5: File {name: "921 crest road (24 of 91).jpg", lastModified: 1579836885360, lastModifiedDate: Thu Jan 23 2020 22:34:45 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 14288288, …}
/// 6: File {name: "921 crest road (25 of 91).jpg", lastModified: 1579836886846, lastMod
console.log(file.current) //// undefined
}
async function handleSubmit(event) {
event.preventDefault();
setShowLoading(true);
try {
console.log(file.name) ///undefined
const filename = `${job.jobId}---${file.name}`;
const stored = await Storage.put(filename, file.current, {
contentType: file.type
});
} catch (e) {
alert(e);
console.log(e.message)
}
setShowLoading(false);
}
var centerText = {textAlign: "center"}
return(
<IonPage>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton/>
</IonButtons>
<IonTitle>Upload Images</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding">
<form onSubmit={handleSubmit}>
<input multiple="true" type="file" onChange={(e) => handleFileChange(e)}></input>
<IonButton expand="block" color="primary" strong="true" size="default" type="submit" >Upload</IonButton>
</form>
</IonContent>
</IonPage>
);
}
export default withRouter(JobInfo);
已更新代码 -- 仍然无法正常工作!
const file = useRef(null);
function extractInfo(file) {
console.log(file)
return {
name: file.name,
type: file.type,
content: btoa(file.content),
};
}
async function handleFileChange(event) {
file.current = event.target.files;
}
async function handleSubmit(event) {
const result = await Promise.all(
file.current.files
.map(extractInfo)
.map(uploadFile)
);
console.log(file.files)
}
async function uploadFile(file) {
setShowLoading(true);
try {
const filename = `${job.jobId}-${file.name}`;
const stored = await Storage.put(filename, file.current, {
contentType: file.type
});
} catch (e) {
alert(e);
console.log(e.message)
}
setShowLoading(false);
}
var centerText = {textAlign: "center"}
return(
<IonPage>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton/>
</IonButtons>
<IonTitle>Upload Images</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding">
<form onSubmit={handleSubmit}>
<input multiple type="file" ref={file} onChange={(e) => handleFileChange(e)}></input></input>
<IonButton expand="block" color="primary" strong="true" size="default" type="submit" >Upload</IonButton>
</form>
</IonContent>
</IonPage>
);
}
export default withRouter(JobInfo);
您忘记在输入元素中使用 ref。 使用 Promise.all 链接所有的承诺。
所以你的问题可以通过这样的方式解决:
const { useState, useRef } = React;
function Uploader() {
const file = useRef({});
function readContent(file) {
return new Promise((accept, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => accept({
name: file.name,
type: file.type,
content: reader.result
});
reader.onerror = () => reject();
});
}
function upload(file) { // fake upload
return new Promise(accept => {
setTimeout(() => accept(file), 1000);
});
}
function onSubmit(event) {
event.preventDefault();
const filesAsArray = [...file.current.files];
const fileInfo = Promise.all(filesAsArray.map(readContent))
.then(files => Promise.all(files.map(upload)))
.then(console.log);
return false;
}
return (
<div>
<form onSubmit={onSubmit}>
<input ref={file} type="file" multiple={true} />
<input type="submit" value="Upload" />
</form>
</div>
);
}
ReactDOM.render(<Uploader />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>