When my browser downloads an image from a web site, there is no base64 encoding involved. It issues an HTTP command like GET /image.jpg
and receives an HTTP response whose Content-Type
is something like image/jpg
, whose Content-Length
is the number of bytes in the image, and whose body is the raw binary image data itself. The data is neither encoded using a character set, nor encoded using a scheme like base64.
Writing RESTful resources has trained me to expect symmetry between HTTP GET
and PUT
so that, for example, a URL that delivers JSON data when I do a GET
will then accept JSON data when it is presented with a PUT
. In neither case is form encoding involved; in both cases there is simply a Content-Length
giving the number of bytes in the payload, a Content-Type
header declaring that the payload is JSON in some character set, and then the character data sits alone and unadorned as the body of the GET
or PUT
.
I am writing a PhoneGap application that lets users take photographs and them upload them using my application. I had expected that I could design a RESTful interface for this, that supports symmetric GET
and PUT
— so that PUT
commands involve no special encoding, nor involve any idea of a character set, but simply have a Content-Type
of image/jpg
and then a mass of binary JPG data as their payload. Obviously this is a more efficient use of bandwidth than trying to encode the image inside of a form. And this approach works fine when I PUT
to a URL using a tool like curl
.
But I am having no luck in doing a clean RESTful PUT
from PhoneGap WebKit JavaScript! PhoneGap is willing to return the image to my JavaScript as either a local file:
URL, or else as a data:
URL that carries the image data inline courtesy of base64 encoding. But in neither case can I find a clear way to convert the image into a pure binary format (would I use one of those newfangled Blob
objects for this? if so, how?) and then cause a PUT
that, without festooning the request with extra layers of form or encoding cruft, will simply transmit the raw image across the wire to my web server as the HTTP request payload.
Does anyone know how to induce WebKit to PUT
an AJAX request with a raw image as its body? Thanks for any pointers — or even any useful answers to the effect that I am approaching this all wrong!
As for the binary image processing, the Binary File Inspector demo might be helpful as an end-to-end example.
There's some tutorial information on the subject of getting Blob
s from the filesystem at MDN. This blog post describes how to turn a base64 URI into an ArrayBuffer
and then a Blob
.
Finally, either an ArrayBuffer
or a Blob
can be uploaded using the XMLHttpRequest2
interface.
The XHR2 spec seems to imply that PUT
is supported, along with a bunch of other HTTP methods. So combining all this you could stuff files in Blob
s and send them up using XHR2.
Untested code sample using the base64 decoding method with some help from base64-binary.js:
var BASE_64_PREFIX = "base64,";
function getBase64Content(base64Uri) {
var index = base64Uri.indexOf(BASE_64_PREFIX);
return base64Uri.substring(index + BASE_64_PREFIX.length);
}
function put(uri, data, onComplete) {
var xhr = new XMLHttpRequest();
xhr.open("PUT", uri, true);
xhr.onload = onComplete;
xhr.send(data);
}
var base64Uri = fromPhoneGap();
var base64Content = getBase64Content(base64Uri);
var arrayBuffer = Base64Binary.decodeArrayBuffer(base64Content);
put("/some/uri", arrayBuffer, function () {
console.log("All done");
});
That said, I doubt much of this works on even the latest desktop WebKit, much less the version you're going to be saddled with via PhoneGap. You're probably not in good shape to take advantage of these draft specifications.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With