// See also: http://www.aaronland.info/weblog/2014/09/22/desire/#upload function upload_init(){ $("#upload-form").submit(function(){ try { var photos = $("#photo"); var files = photos = photos[0].files; var file = files[0]; var reader = new FileReader(); reader.onload = function(evt){ var data_uri = evt.target.result; var dt = new Date(); var pending_id = window.btoa(dt.toISOString()); var key = "upload_" + pending_id; localforage.setItem(key, data_uri, function(rsp){ upload_process_pending(pending_id); }); }; reader.readAsDataURL(file) } catch(e){ console.log("Hrm, there was a problem uploading your photo.", e); return false; } return false; }); upload_clear_processing(); setInterval(upload_process_pending, 30000); } function upload_clear_processing(){ var re = /processing_(.*)/; localforage.keys(function(rsp){ var count = rsp.length; for (var i=0; i < count; i++){ var m = rsp[i].match(re); if (m){ localforage.removeItem(m[0], function(){ console.log("unset " + m[0]); }); } } }); } function upload_process_pending(){ var re = /upload_(.*)/; localforage.keys(function(rsp){ var count = rsp.length; for (var i=0; i < count; i++){ var m = rsp[i].match(re); if (m){ console.log("process pending id " + m[1]); upload_process_pending_id(m[1]); } } }); } function upload_process_pending_id(pending_id){ var processing_key = "processing_" + pending_id; var upload_key = "upload_" + pending_id; console.log("process id: " + processing_key); console.log("process id: " + upload_key); localforage.getItem(processing_key, function(rsp){ if (rsp){ console.log("got processing key, so skipping"); return; } var dt = new Date(); var ts = dt.getTime(); localforage.setItem(processing_key, ts, function(rsp){ console.log("set " + processing_key + ", to " + ts); localforage.getItem(upload_key, function(data_uri){ console.log("got data uri for " + upload_key); try { var blob = upload_data_uri_to_blob(data_uri); } catch(e){ console.log("failed to create a blob for " + upload_key + ", because " + e); return false; } upload_do_upload(blob, pending_id); }); }); }); } function upload_do_upload(file, pending_id){ console.log("do upload for " + pending_id); var data = new FormData(); data.append('photo', file); var on_success = function(rsp){ console.log(rsp); var processing_key = "upload_" + pending_id; var upload_key = "upload_" + pending_id; localforage.removeItem(upload_key, function(rsp){ console.log("removed " + upload_key); localforage.removeItem(processing_key, function(rsp){ console.log("removed " + processing_key); }); }); }; var on_error = function(rsp){ console.log(rsp); var processing_key = "processing_" + pending_id; localforage.removeItem(processing_key, function(rsp){ console.log("removed " + processing_key); }); var details = ''; try { var rsp = JSON.parse(rsp['responseText']); details = rsp['error']['message']; console.log(details); } catch(e){ console.log(e); } }; $.ajax({ url: 'https://upload.example.com/', type: "POST", data: data, cache: false, contentType: false, processData: false, dataType: "json", success: on_success, error: on_error, }); return false; } // http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata function upload_data_uri_to_blob(data_uri){ // convert base64/URLEncoded data component to raw binary data held in a string var byteString; if (data_uri.split(',')[0].indexOf('base64') >= 0){ byteString = atob(data_uri.split(',')[1]); } else { byteString = unescape(data_uri.split(',')[1]); } // separate out the mime component var mimeString = data_uri.split(',')[0].split(':')[1].split(';')[0] // write the bytes of the string to a typed array var ia = new Uint8Array(byteString.length); for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ia], {type:mimeString}); }