1

I am trying to create a web API that allows someone (well, preferably a program) to submit a large binary file and receive an ID for that file in return. I have some HTML with a form (method="POST") and an <input type="file" ...> element that can submit a file to some PHP code, using the standard multipart/form-data MIME type. The PHP generates the ID and prints it out as its result. Because the PHP simply prints the ID, as opposed to redirecting to another HTML page or generating HTML itself, it is not very pretty, but hopefully is sufficient for the intended use case of a programmatic file submit API.

So far, so good. It gets tricky when I want to have client-side code capture the returned ID and invoke other APIs with it. If the client is a web page with JavaScript, it seems like the client should use XMLHttpRequest, but it is not clear to me how to get that object to use the file the user selected with the file input control.

I would love for the same API to work both with manually operated web forms (for easy UI and testing), and purely programmatic invocation (like with JavaScript, curl/libcurl, etc.). I don't want the PHP to issue a redirect to another page with the ID in the query string, and I don't want to return HTML directly. I just want a simple file in, ID out API.

Since this is proving difficult I suspect I am going about things the wrong way. I am open to alternative designs, but I would prefer to keep things as simple as possible. I found a somewhat similar question, but it is too Java-centric and doesn't quite address my problem.

2
  • Is your question "How can I use JavaScript to upload a user selected file and capture the returned document?"? That seems to be the only problem you are having, but your concern otherwise seems to be with the design of the server side of this. Commented Oct 15, 2012 at 6:17
  • More or less. The file can be user-selected (like in a form), or programmatically supplied (like from a script). The returned document is really just an ID, with whatever packaging makes sense, and that is usable by client-side JavaScript. My concern is that the server side code is compatible with my client-side use cases. I am happy to adjust either to solve the problem. Commented Oct 15, 2012 at 6:21

2 Answers 2

1

I had to do something similar, and what I ended up doing was submitting the form to a hidden iframe. The response from the php can then simply be retrieved in an iframe onload handler.

In fact, here is the code I used:

 $('submitdestination').onload=function(){ var appID=this.contentDocument.body.children[0].innerHTML; //did something with appID new mBox.Notice({type: 'ok',delayClose: 1000,content: 'Data saved.',position: {y: 'bottom',x: 'right'}});//displayed message } $('cvdetails').submit(); 

Note: submitdestination is my iframe. cvdetails is my form. The target for the form was set to submitdestination. Also, I am using Mootools, in case any one noticed the missing hash in my dollar arguments.

Here is a stripped down version of the HTML I used (although the iframe is unchanged):

<form id="cvdetails" name="cvdetails" action="scripts/upload.php" method="post" enctype="multipart/form-data" target="submitdestination" autocomplete="off"> <button type="button" id="save" class="mainbutton">Save</button> </form> <iframe id="submitdestination" name="submitdestination" style="display:none" ></iframe> 

The save button had a click handler that could be reduced to:

$('save').addEvent('click',function(evt){evt.stop();$('cvdetails').submit();}) 
Sign up to request clarification or add additional context in comments.

5 Comments

As I was researching this, I saw mention of the hidden iframe approach, but I didn't think to capture the response in the onload handler. Could you please link to or post some sample code? I think people would benefit from seeing it all together.
I have posted the code. My case is more similar to yours than I had thought, although I was outputting one or two elements in the body tag of the response html. The first child contained the ID of the applicant (this was for generating company format word CVs)
Sorry to bug you again, @Asad, but could you also post the HTML for the hidden iframe and the form that submits to it? I'de love to see all the components at once.
I cannot post my exact HTML, which is generated by php, but I am adding a simplified version to the answer above. I'd like to make a fiddle for this, but it pertains simultaneously to client side and server side script, which complicates things.
Thanks for the examples, @Asad. You really helped me solve the problem. Enjoy the 25 points. :)
0

Thanks to @Asad's help I was able to get things working the way I wanted. Putting it all together, I have essentially this code:

<html> <head> <script type="text/javascript"> window.onload = function(){ setUploadID(-1); document.getElementById('hidden_iframe').onload = captureUploadID; } function setUploadID(id) { document.getElementById('upload_id').innerHTML = id; } function captureUploadID() { var upload_id = this.contentDocument.body.childNodes[0].textContent; setUploadID(upload_id); } </script> </head> <body> <form action="upload.php" enctype="multipart/form-data" method="POST" target="hidden_iframe"> File: <input type="file" name="media" /><br> <input type="submit" value="Upload" /> </form> <br> Upload ID: <span id="upload_id"></span> <iframe id="hidden_iframe" style="display: none;"></iframe> </body> </html> 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.