What format (MIME Type) should I use for HTML5 drag and drop operations?
Asked Answered
T

3

24

I'm starting to experiment with HTML5 Drag and Drop. Then, in the dragstart event handler we should run setData(), which receives two parameters: format and data.

function dragstart_handler(ev) {
    ev.dataTransfer.setData('text/plain', 'foobar');
}

I want to drag some kind of "object" from one container into another container, inside my web application. By "object", I mean something that has multiple attributes (color, text, author, date, …).

What kind of format (or MIME Type) should I use?

  • text/plain?
  • text/x-myapp-myobjtype?
  • application/x-myapp-myobjtype?
  • application/x-myapp.myobjtype+json?
  • something else?
  • more than one?

How should I encode my object (the data parameter of setData())?

  • Comma-separated (or any other delimiter) key=value pairs?
  • Serialize the object using JSON?
  • Just an id, and at the dropzone I must retrieve the full object using just the id?
  • Send just a reference to the object, without even serializing anything? (not possible, the data argument must be a string)

(I realize that "How to enconde an object for Drag and Drop" could be another question here, but it is closely related to the choice of MIME Type)


Some references:

Tenebrae answered 20/7, 2011 at 19:5 Comment(3)
It really depends on exactly what you're doing, but 'application/json' and a JSON serialized object seem like decent choices...Murtagh
But isn't application/json something too generic? Following that suggestion, then any OpenOffice document should have application/zip MIME type as well, since they are actually zipped files.Swayne
Further improving my point: if I were to use application/json, then, by analogy, all SVG images should have been application/xml instead of image/svg+xml, since they are also XML documents. The same logic would apply to anything that is serialized using XML (like Google Earth KML files, that currently use application/vnd.google-earth.kml+xml type; or Atom feeds, that use application/atom+xml).Swayne
T
14

The HTML5 specification has some drag and drop examples (see the current working draft or the latest version). In such examples, a custom MIME Type is used, and the use of site-specific MIME types is also suggested. See this snippet:

<p>Drop your favorite fruits below:</p>
<ol dropzone="move s:text/x-example" ondrop="dropHandler(event)">
 <-- don't forget to change the "text/x-example" type to something
 specific to your site -->
</ol>
<script>
  var internalDNDType = 'text/x-example'; // set this to something specific to your site
[...]

So, that's great, this means we should use a custom MIME type! (unless we are actually dragging plain text, or just a URL, or something that already has a well-known type)

But how do we create such custom MIME type?

I found no documentation about this, so I looked at other MIME types. The list of text media types had nothing special, but the list of application media types was quite interesting. Let me grab a sample from that list:

application/atom+xml
application/xhtml+xml
application/xmpp+xml

application/vnd.google-earth.kml+xml
application/vnd.google-earth.kmz
application/vnd.iptc.g2.newsitem+xml
application/vnd.iptc.g2.packageitem+xml
application/vnd.nokia.iptv.config+xml
application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml
application/vnd.yamaha.openscoreformat.osfpvg+xml

application/vnd.hal+json
application/vnd.hal+xml

I can notice a pattern for making names:

  • A dot hierarchically separates multiple "elements" (for instance, config is child of iptv, that is child of nokia, that is child of vnd).
  • A hyphen separates composite words (as in google-earth and openxmlformats-officedocument).
  • A plus sign serves to further specify the serializing format (+json and +xml in these examples).
  • The x- prefix should be used for MIME types not registered with IANA (and, thus, not shown on that list).

Based on these rules, I can suggest using the following MIME type:

application/x-mysite.myobject+json (or application/x-mysite.parentobject.childobject+json)

This seems to be the most precise and correct way to specify a custom MIME type for a web application object encoded in JSON.

Tenebrae answered 29/7, 2011 at 18:25 Comment(2)
Shouldn't the "x-" prefix be replaced by "vnd."?Legere
x- prefix is to be used for MIME types that are not registered with IANA. The vnd. prefix, however, is for vendor-specific MIME types that have been registered with IANA. (Good question, by the way!)Swayne
T
6

Update: this Chrome bug has been fixed since version 19.

If I aim to support Google Chrome (version 12 is the latest one now), then I must stick to text/plain.

That's because Chrome has improperly implemented the dataTransfer object, and there is an open bug about dataTransfer not working with non text or url.

I've written a simple desmontration at jsFiddle. It works correctly in Mozilla Firefox 3.6 and even in Arora browser (version 0.10.2, WebKit version 533.3). Just for completeness, my Chrome version is 12.0.742.112 (WebKit version 534.30). The demonstration code is also available below:

<div id="drag" draggable="true">Drag me!</div>
<div id="drop">Drop here!</div>


#drag, #drop {
    padding: 1em 2em;
    margin: 1em 0;
}
#drag {
    background: #CFC;
}
#drop {
    background: #FCC;
}


function dragstart_handler(ev) {
    console.log('dragstart');
    ev.dataTransfer.setData('text/x-example', 'Foobar');
}

function dragover_handler(ev) {
    // Accepting whatever is dragged over here
    ev.preventDefault();
}

function drop_handler(ev) {
    console.log('drop');
    console.log(ev.dataTransfer.types);

    if (ev.dataTransfer.types) {
        var i;
        for (i = 0; i < ev.dataTransfer.types.length; i++) {
            var type = ev.dataTransfer.types[i];
            console.log(type, ev.dataTransfer.getData(type));
        }
    }

    console.log(ev.dataTransfer.getData('text/x-example'));
}

var drag = document.getElementById('drag');
drag.addEventListener('dragstart', dragstart_handler, false);

var drop = document.getElementById('drop');
drop.addEventListener('dragover', dragover_handler, false);
drop.addEventListener('drop', drop_handler, false);
Tenebrae answered 22/7, 2011 at 18:12 Comment(4)
The Chrome bug was fixed as of version 19.Courtund
And was broken again by version 22 (possibly earlier)Endoplasm
@Endoplasm Running Google Chrome 29.0.1547.62 on Linux. The demonstration linked in my answer works correctly here, so I don't think this bug still exists nowadays. (BTW, Chrome 22 is quite old…)Swayne
It seems broken in IE11 =(Misleading
N
0

Use 'application/json' as a wrapper for any other metadata that you may like, including mime-type of linked files, or the html you want to use in the browser.

{ 'assets': [
      {
       'color': 'foo',
       'text': 'bar',
       'uri': 'http://', // location of asset
       'type': 'application/zip', // mime-type of asset
       'html': '<div>html representation</div>'
       // .. more properties
      }
   // ...more assets
   ]
}
Noncommittal answered 20/7, 2011 at 22:12 Comment(1)
Plain application/json doesn't feel right. Maybe something along the lines application/x-myapp.myobj+json ?Swayne

© 2022 - 2024 — McMap. All rights reserved.