Assuming your Java code is using Apache HttpComponents (what you really should have said then), your code when it is complemented
URI aWebImageUrl2 = new URI("http://localhost:1337/"); File imgPath = new File("โฆ/face.png"); final String aImgCaption = "face";
represents the following example HTTP request (as verified by nc -lp 1337 , see GNU Netcat ):
POST / HTTP/1.1 Content-Length: 990 Content-Type: multipart/form-data; boundary=oQ-4zTK_UL007ymPgBL2VYESjvFwy4cN8C-F Host: localhost:1337 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.1.2 (java 1.5) --oQ-4zTK_UL007ymPgBL2VYESjvFwy4cN8C-F Content-Disposition: form-data; name="picture"; filename="face.png" Content-Type: application/octet-stream PNG[โฆ]
The simplest solution to do something similar in HTML is, of course, using the FORM element and the absence or minimal client-side scripting:
<form action="http://service.example/" method="POST" enctype="multipart/form-data"> <input type="file" name="picture"> <input type="submit"> </form>
which sends (either when sending using the submit button, or in the form of a submit() object), the following request:
POST / HTTP/1.1 Host: localhost:1337 Connection: keep-alive Content-Length: 886 Cache-Control: max-age=0 Origin: http://localhost User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1 Content-Type: multipart/form-data; boundary=
But since you directly asked about the "javascript" solution (there really is no such programming language there ), I believe that you want to have more client-side control over the sending process. In this case, you can use the W3C and XMLHttpRequest or XMLHttpRequest2 API file APIs, as shown in recent browsers (and not programming languages):
<script type="text/javascript"> function isHostMethod(obj, property) { if (!obj) { return false; } var t = typeof obj[property]; return (/\bunknown\b/i.test(t) || /\b(object|function)\b/i.test(t) && obj[property]); } var global = this; function handleSubmit(f) { if (isHostMethod(global, "XMLHttpRequest")) { try { var input = f.elements["myfile"]; var file = input.files[0]; var x = new XMLHttpRequest(); x.open("POST", f.action, false); // ยน try { var formData = new FormData(); formData.append("picture", file); x.send(formData); return false; } catch (eFormData) { try { var reader = new FileReader(); reader.onload = function (evt) { var boundary = "o" + Math.random(); x.setRequestHeader( "Content-Type", "multipart/form-data; boundary=" + boundary); x.send( "--" + boundary + "\r\n" + 'Content-Disposition: form-data; name="picture"; filename="' + file.name + '"\r\n' + 'Content-Type: application/octet-stream\r\n\r\n' + evt.target.result + '\r\n--' + boundary + '--\r\n'); }; reader.readAsBinaryString(file); return false; } catch (eFileReader) { } } } catch (eFileOrXHR) { } } return true; } </script> <form action="http://service.example/" method="POST" enctype="multipart/form-data" onsubmit="return handleSubmit(this)"> <input type="file" name="myfile"> <input type="submit"> </form>
This approach attempts to use the XMLHttpRequest API. If this fails, the function returns true , so true returned to the event handler (see Attribute Value), and the form is submitted in the usual way (the latter may not work with your web service; disabling script support).
If XMLHttpRequest can be used, it is "checked" ยฒ if the input to the file has the files property and the referenced object has the 0 property (referring to the first control selected for this form, if supported).
If so, the XMLHttpRequest2 API is checked, the send() method can refer to FormData and do everything multi - Magic by itself. If the XMLHttpRequest2 API is not supported (which should throw an exception), the File API FileReader checked, which can read the contents of the File as a binary string ( readAsBinaryString() ); if it is successful ( onload ), the request is prepared and sent. If one of these approaches seems to work, the form does not appear ( return false ).
An example of a query submitted using this code using the FormData API:
POST / HTTP/1.1 Host: localhost:1337 Connection: keep-alive Content-Length: 887 Origin: http://localhost User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryLIXsjWnCpVbD8FVA Accept: */* Referer: http://localhost/scripts/test/XMLHTTP/file.html Accept-Encoding: gzip,deflate,sdch Accept-Language: de-CH,de;q=0.8,en-US;q=0.6,en;q=0.4 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 ------WebKitFormBoundaryLIXsjWnCpVbD8FVA Content-Disposition: form-data; name="picture"; filename="face.png" Content-Type: image/png PNG[โฆ]
The request example looks slightly different when the FileReader API was used instead (as a proof of concept):
POST / HTTP/1.1 Host: localhost:1337 Connection: keep-alive Content-Length: 1146 Origin: http://localhost User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1 Content-Type: multipart/form-data; boundary=o0.9578036249149591 Accept: */* Referer: http://localhost/scripts/test/XMLHTTP/file.html Accept-Encoding: gzip,deflate,sdch Accept-Language: de-CH,de;q=0.8,en-US;q=0.6,en;q=0.4 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 --o0.9578036249149591 Content-Disposition: form-data; name="picture"; filename="face.png" Content-Type: application/octet-stream PNG[โฆ]
Please note that XMLHttpRequest2, FormData and File API have only the status of a working project and are still in motion. In addition, this approach works if the provided resource and the provided resource use the same protocol, domain, and port number; you may have to deal with and work around the same origin policy . If necessary, add functional tests and more exception handling.
Also note that a request made using FileReader is larger with the same file and skips the main character, as indicated in the question mentioned by Fritz van Kampen. This may be due to an error (WebKit), and then you can remove this alternative; suffice it to say that the readAsBinaryString() method is deprecated already in the File API Working Draft in favor of readAsArrayBuffer() , which Typed Arrays should use.
See also "Using Files from Web Applications" .
ยน Use true for asynchronous processing; this avoids blocking the user interface, but requires that you do the processing in the event listener, and you always have to cancel the form submission (even if the XHR was unsuccessful).
ยฒ If access to the resource is not possible, an exception will be thrown. If you prefer a real test, do (optional) testing functions (instead) and keep in mind that not everything can be safely tested.