Skip to content

Instantly share code, notes, and snippets.

@tankakatan
Created August 31, 2022 12:49
Show Gist options
  • Save tankakatan/7e19d9359eef133438316aa7eef976fc to your computer and use it in GitHub Desktop.
Save tankakatan/7e19d9359eef133438316aa7eef976fc to your computer and use it in GitHub Desktop.
Multipart/form-data upload test
/* eslint-disable no-console */
(() => {
/**
* Usage:
* • Run Point Engine
* • Open Point Browser or a browser configured to use HTTPS proxy at localhost:8666
* • Load https://point
* • Open browser console
* • Copy and paste the contents of this file into the console prompt and hit enter
* • The web page contents will be replaced with the HTML generated below
* • Choose a file to upload
* • Choose whether or not to use Point SDK (requires SDK installation)
* • Choose upload method – the problematic one is "Upload Form"
*/
const input = document.createElement('input');
input.type = input.name = 'file';
input.accept = 'image/gif,image/png,image/jpeg,image/bmp,' +
'image/webp,video/webm,video/ogg,video/mp4,video/mpeg';
const preview = document.createElement('img');
preview.style = 'height: 250px; width: auto;';
preview.alt = 'Image preview';
input.onchange = () => {
preview.src = input.files.length ? URL.createObjectURL(input.files[0]) : '';
};
const checkbox = document.createElement('input');
const label = document.createElement('label');
checkbox.type = checkbox.id = label.for = 'checkbox';
checkbox.name = 'sdk';
checkbox.checked = typeof window.point === 'object';
checkbox.disabled = window.point === undefined;
label.innerHTML = 'Use SDK';
const uploadForm = document.createElement('button');
const uploadBlob = document.createElement('button');
uploadForm.innerHTML = 'Upload Form';
uploadBlob.innerHTML = 'Upload Blob';
const uploadWithTimeout = (body) => {
const upload = () => checkbox.checked
? window.point.storage.postFile(body)
: fetch('https://point/_storage', {method: 'POST', body}).then(res => res.json());
return Promise.race([upload(), new Promise((_, reject) => setTimeout(() => reject(
new Error('Timeout error')
), 30_000))]);
};
uploadForm.onclick = async () => {
if (!input.files.length) {
alert('Please select a file to upload');
return;
}
const body = new FormData();
body.append('postfile', input.files[0]);
try {
console.info('Uploading from data', body);
const {data: hash} = await uploadWithTimeout(body);
console.log('Successfully uploaded data at', hash);
} catch (e) {
console.error('Failed to upload form data', body, e);
}
};
uploadBlob.onclick = async () => {
if (!input.files.length) {
alert('Please select a file to upload');
return;
}
const DataURIToBlob = (dataURI) => {
const splitDataURI = dataURI.split(',');
const byteString = splitDataURI[0].indexOf('base64') >= 0
? atob(splitDataURI[1])
: decodeURI(splitDataURI[1]);
const mimeString = splitDataURI[0].split(':')[1].split(';')[0];
const ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type: mimeString});
};
const data = await new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(input.files[0]);
reader.onload = e => resolve(e.srcElement.result);
reader.onerror = reject;
});
const body = new FormData();
const blob = DataURIToBlob(data);
body.append('postfile', blob);
try {
console.log('Uploading blob:', {body, blob});
const {data: hash} = await uploadWithTimeout(body);
console.log('Successfully uploaded blob at', hash);
} catch (e) {
console.error('Failed to upload blob', body, e);
}
};
const container = document.createElement('div');
const imgContainer = document.createElement('div');
const cbContainer = document.createElement('div');
cbContainer.append(checkbox, label);
imgContainer.appendChild(preview);
container.append(input, cbContainer, uploadForm, uploadBlob, imgContainer);
document.body.innerHTML = '';
document.body.appendChild(container);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment