Upload image to web service in JavaScript

I need to upload an image to a web service from javascript. I need to send json string to file (image). In java we have MultipartEntity . I have the following code in java:

 HttpPost post = new HttpPost( aWebImageUrl2 ); MultipartEntity entity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE ); // For File parameters entity.addPart( "picture", new FileBody((( File ) imgPath ))); // For usual String parameters entity.addPart( "url", new StringBody( aImgCaption, "text/plain", Charset.forName( "UTF-8" ))); post.setEntity( entity ); 

Now I need to do the same image loading in javascript.
But in javaScript, I did not find the equivalent of MultipartEntity. Offer any solutions.

+7
source share
5 answers

To upload images, I use the Valum ajax upload plugin or jQuery form plugin , which allows you to submit a regular form using the ajax method.

If you will use POST requests, do not forget to use the hidden attribute MAX_FILE_SIZE:

<input type="hidden" name="MAX_FILE_SIZE" value="20000000">

Note that it must precede the file input field. It is in bytes, so this will limit the download to 20 MB. See the PHP documentation for more details.

+4
source

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"; // โ€ฆ HttpClient httpClient = new DefaultHttpClient(); httpClient.execute(post); 

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=----WebKitFormBoundaryhC26St5JdG0WUaCi Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 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 ------WebKitFormBoundaryhC26St5JdG0WUaCi Content-Disposition: form-data; name="picture"; filename="face.png" Content-Type: image/png  PNG[โ€ฆ] 

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.

+2
source

you can really call the service using javascript, here is a sample code here

if your requirement is to load an image and make a webservice call from JS, then it can be tricky.

you can just upload the image to the server and call the server on the web service, there are many tools to help you upload the file to the server .

0
source

MultipartEntity sounds like Multipart/form-data .

You can use regular XMLHttpRequest to execute a POST request. You can use HTML 5 FormData to create your Multipart/form-data request.

Here's an example: the HTML5 readAsBinaryString API reads files much more than files on disk

0
source

I have done this before and it works using the HTML5 canvas element. I will use jQuery here. I accept a general 300px by 300px image.

First add a hidden canvas to the page:

 $("body").append('<canvas id="theCanvas" style="display:none" width="300px" height="300px"></canvas>'); 

Then upload the image to the canvas:

 var canvas = document.getElementById('theCanvas'); var context = canvas.getContext('2d'); var imageObj = new Image(); imageObj.src = "/path/to/image.jpg"; context.drawImage(imageObj, 0, 0, 300, 300); 

Now you can access what's on the canvas as a data string and send it to the web service using the jQuery mail function:

 $.post("path/to/service", {'image':canvas.toDataURL("image/png"), 'url':'caption'}, function(file){ //Callback code }); 
0
source

All Articles