Lately, I've encountered issues with pre-signed post uploads to S3 that seem to be unique to Mobile Safari browsers. Interestingly, the error has also shown up occasionally on Desktop Safari.
Whenever this error occurs, it triggers a response from S3 indicating an "EntityTooSmall
" code along with details about the proposed upload size being smaller than the minimum allowed size.
It's worth noting that the code used for presigning the S3 URL and uploading files functions smoothly on other browsers such as Chrome, Firefox, and Brave.
The problem seems to be related to how Safari handles appending file data to the FormData object, resulting in sporadic failures that are hard to pinpoint.
While Safari accurately reads the file size (used for creating the presigned URL), there appears to be an issue when attaching it to the form data object for upload.
The following code snippet is what works reliably on most browsers but experiences intermittent failures on Safari:
<script>
import axios from 'axios'
import getPresignUrl from './presign'
// Vue Component
export default {
name: 'FinickyOnSafariUploader'
data: () => ({
// ...
}),
methods: {
presignAndUpload (file) {
const fileData = {
fileName: file.name,
fileType: file.type,
fileSize: file.size
}
getPresignUrl(fileData)
.then((resp) => {
const presignFields = resp.data.presignFields
const presignUrl = resp.data.presignUrl
return this.uploadToS3(file, presignUrl, presignUrl, presignFields)
})
},
uploadToS3 (file, presignUrl, presignFields) {
formPostData = new FormData()
for (const field in presignFields) {
formPostData.append(field, presignFields[field])
}
formPostData.append('Content-Type', file.type)
formPostData.append('file', file)
const req = {
url: presignUrl,
method: 'POST',
headers: { 'Content-Type': 'multipart/form-data' },
data: formPostData
}
return axios.request(req)
}
}
}
</script>
If anyone has any insights or suggestions on why these sporadic issues occur specifically on Safari, your feedback would be greatly appreciated.