I have created a test contact form where a user can upload an image attachment.
- The presignedURL AWS Lambda function works fine
- The image file (blob) is showing up as an image in the html, so it's added correctly
- When image is posted, I get a successful 200 response and the file appears in S3
However, in S3 all files appear empty. The size seems to change depending on the length of the link size (e.g. blob is 63B, a hard-coded link varies in size), so it seems like it just takes the link as data, not the actual image. I checked many times if my axios syntax is correct and went through numerous threads here in SO but can't figure out what am I doing wrong.
AWS Lambda to generate the presigned URL:
const AWS = require('aws-sdk')
AWS.config.update({ region: 'eu-west-2' })
const s3 = new AWS.S3();
const uploadBucket = 'xxx-bucket'
exports.handler = async (event) => {
const result = await getUploadURL()
console.log('Result: ', result)
return result
};
const getUploadURL = async function() {
console.log('getUploadURL started')
let actionId = Date.now()
var s3Params = {
Bucket: uploadBucket,
Key: `${actionId}.jpg`,
ContentType: 'image/jpeg',
CacheControl: 'max-age=31104000',
ACL: 'public-read'
};
return new Promise((resolve, reject) => {
// Get signed URL
let uploadURL = s3.getSignedUrl('putObject', s3Params)
resolve({
"statusCode": 200,
"isBase64Encoded": false,
"headers": {
"Access-Control-Allow-Origin": "*"
},
"body": JSON.stringify({
"uploadURL": uploadURL,
"photoFilename": `${actionId}.jpg`
})
})
})
}
React Frontend:
class QuoteForm extends Component {
constructor(props) {
super(props);
this.state = {
file:null,
};
};
onContactNameChange(e){
this.setState({ContactName:e.target.value});
};
onFileChange(e){
let [file] = e.target.files;
if (file) {
this.setState({
file: URL.createObjectURL(e.target.files[0]),
});
console.log(file);
}
};
async handleSubmit(e){
e.preventDefault();
axios.post(`https://xxxx/`)
.then(res => {
console.log(res)
const url = res.data.uploadURL;
const axiosConfig = {
headers: {
"Content-Type": "image/jpeg",
"Cache-Control": 'max-age=31104000'
}
}
axios.put(url, this.state.file, axiosConfig)
.then(response => {console.log(response)}).catch(err => {console.log(err.response)
});
});
}
render() {
return (
<form onSubmit={this.handleSubmit.bind(this)}>
<input
type="file"
name="file"
id="fileUpload"
onChange={this.onFileChange.bind(this)}
/>
<img src={this.state.file} alt="img" />
<button
className="large"
style={{marginTop:"1.25rem"}} >
Submit
</button>
</form>
);
}
}
I just can't understand why the files in S3 bucket turn up empty.
