There is no direct way to pass pure binary data to the WP upload object. Only File based objects will be processed. I had to create a separate XmlHttpRequest
. (Simply using $.ajax()
did not work and resulted in polluted Image data.)
After successfully uploading the image data to async-upload.php I was able to fire a ‘FileUploaded’ event, along with what the server responded. After this the image show up in the media library.
The code example above could look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | <script type="text/javascript"> (function($){ var media = wp.media, frame, l10n = media.view.l10n = typeof _wpMediaViewsL10n === 'undefined' ? {} : _wpMediaViewsL10n; // override router creation media.view.MediaFrame.Post.prototype.browseRouter = function( view ) { view.set({ upload: { text: l10n.uploadFilesTitle, priority: 20 }, dataurltest: { text: 'DataUrl Test', priority: 30 }, browse: { text: l10n.mediaLibraryTitle, priority: 40 } }); }; var bindHandlers = media.view.MediaFrame.Post.prototype.bindHandlers, dataUrlTest, frame; media.view.MediaFrame.Post.prototype.bindHandlers = function() { // bind parent object handlers bindHandlers.apply( this, arguments ); // bind our create handler. this.on( 'content:create:dataurltest', this.dataurltestContent, this ); frame = this; }; media.view.MediaFrame.Post.prototype.dataurltestContent = function( content ){ // generate test content var state = this.state(); this.$el.removeClass('hide-toolbar'); dataUrlTest = new media.view.dataUrlTest({}); content.view = dataUrlTest; } media.view.dataUrlTest = media.View.extend({ // our test view tagName: 'div', className: 'data-url-test', initialize: function() { _.defaults( this.options, { }); var self = this, blob; // add image with data-url to panel content var b64Data = 'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAGXRFWHRTb2Z0d2F'+ 'yZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bX'+ 'AAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTe'+ 'k5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8i'+ 'IHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjA'+ 'xMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPS'+ 'JodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gP'+ 'HJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8v'+ 'bnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmF'+ 'kb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG'+ '9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yV'+ 'G9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5z'+ 'dGFuY2VJRD0ieG1wLmlpZDpGN0NENTMwNzdCNzcxMUUzQTBFQzg3RURFQTJCNTM'+ '5QiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpGN0NENTMwODdCNzcxMUUzQT'+ 'BFQzg3RURFQTJCNTM5QiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0Y'+ 'W5jZUlEPSJ4bXAuaWlkOkY3Q0Q1MzA1N0I3NzExRTNBMEVDODdFREVBMkI1MzlC'+ 'IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkY3Q0Q1MzA2N0I3NzExRTNBMEV'+ 'DODdFREVBMkI1MzlCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+ID'+ 'wveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+wqqcoQAAAAZQTFRFAAAA/'+ '///pdmf3QAAABFJREFUeNpiYBgFo4D6ACDAAAJYAAFvc4UPAAAAAElFTkSuQmCC', imageUrl = 'data:image/png;base64,' + b64Data, $img = $('<img src="'+imageUrl+'" />') .appendTo(this.$el); // add a submit link $('<a href="#" class="test-send">Okay</a>') .insertAfter($img) .on('click',null,function(){ // creating a blob would go like this: //blob = window.dataURLtoBlob && window.dataURLtoBlob($img.get(0).src) // create and add item to upload queue var file = {}; var attributes = { file: file, uploading: true, date: new Date(), filename: 'test.png', menuOrder: 0, uploadedTo: wp.media.model.settings.post.id, type : 'image', subtype : 'png', loaded : 0, size : 100, percent : 0 }; file.attachment = wp.media.model.Attachment.create( attributes ); wp.Uploader.queue.add(file.attachment); var post_data = { action : wp.Uploader.defaults.multipart_params.action, _wpnonce : wp.Uploader.defaults.multipart_params._wpnonce, post_id : wp.media.model.settings.post.id } function upload_succes( xhr , httpStatus ) { // this will update the uploaded image in the media library frame.uploader.uploader.uploader.trigger('FileUploaded', file, { response : xhr.responseText, status : httpStatus }); } send_b64_data( b64data , attributes.filename , post_data , upload_succes ); }); }, }); return; })(jQuery); </script> |
The function send_b64_data( b64data , filename , post_data , success_callback )
would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | function send_b64_data( b64data , filename , post_data , success_callback ) { var boundary, dashdash, crlf, multipart_string, file_data_name, name, mime_type , xhr; // setup multipart boundary = '----multipart_boundary'+(new Date().getTime().toString(32))+Math.random().toString(32); dashdash = '--'; crlf = '\r\n'; // build request payload multipart_string = ''; for ( name in post_data ) { multipart_string += dashdash + boundary + crlf + 'Content-Disposition: form-data; name="' + name + '"' + crlf + crlf; multipart_string += unescape(encodeURIComponent(send_data[name])) + crlf; } // add image data mime_type = 'image/png'; file_data_name = 'async-upload'; multipart_string += dashdash + boundary + crlf + 'Content-Disposition: form-data; name="' + wp.Uploader.defaults.file_data_name + '"; filename="' + filename + '"' + crlf + 'Content-Type: ' + mime_type + crlf + crlf + atob( b64data ) + crlf + dashdash + boundary + dashdash + crlf; // build and send request xhr = new XMLHttpRequest() xhr.open("post", wp.Uploader.defaults.url, true); xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); xhr.onreadystatechange = function() { var httpStatus, chunkArgs; if (xhr.readyState == 4 ) { try { httpStatus = xhr.status; } catch (ex) { httpStatus = 0; } if (httpStatus == 200) { // will load contents to file fake success_callback(xhr,httpStatus); } else if ( httpStatus >= 400 ) { // handle error } } } if (xhr.sendAsBinary) { // Gecko xhr.sendAsBinary(multipart_string); } else { // WebKit with typed arrays support var ui8a = new Uint8Array(multipart_string.length); for (var i = 0; i < multipart_string.length; i++) { ui8a[i] = (multipart_string.charCodeAt(i) & 0xff); } xhr.send(ui8a.buffer); } } |
If you like FreeWebMentor and you would like to contribute, you can write an article and mail your article to [email protected] Your article will appear on the FreeWebMentor main page and help other developers.