6

I have a form that uploads a file in an firame to a remote server. As a result at the submission url server returns json data with the result of operation, which my iframe catches.

{'result': 'true' or 'false'}

Now I'd like to retrieve this json as the callback of my iframe. I know that I need jsonp to achieve this since it's a cross-site call. Here's my function with sample code from IBM' site :

function fileUploadFunction(){     
    var fileUploadForm = $('#file_upload_form');
    fileUploadForm.attr('action', uploadURL);
    fileUploadForm.submit();
    $('#upload_target').load(function () {
        alert("IFrame loaded");
            $.getJSON(uploadUrl+"&callback=?", function(data) {
                alert("Symbol: " + data.symbol + ", Price: " + data.price);
            });
    });         
};

But here few problems arise. First - my uploadUrl is just "http://something/" . Do I need it to support calls with $callback= suffix ?
Secondly - server gives response only as a result to file upload. So I need to get the result that is stored in my iframe and not at the specified url. How to solve this ?

Here's the link. Notice hidden iframe inside the form. Result from server shows there. :

http://ntt.vipserv.org/artifact/


EDIT

I've previously tried :

    $('#upload_target').load(function () {
        var ret = frames['upload_target'].document.getElementsByTagName("body")[0].innerHTML;
        var data = eval("("+ret+")");
    });

But it raises 'permissions denied' error.

mastodon
  • 497
  • 5
  • 11
  • 22

5 Answers5

4

This is easily done with easyXDM and there is actually a blog post about this exact use case here.

In essence what it does is use cross-domain messaging to relay the response to the invoking document.

Update: Here is a link for this in action, the source can be found at github, the files are prefixed 'upload_'.

Sean Kinsey
  • 37,689
  • 7
  • 52
  • 71
  • so there's no way I can achieve this without introducing some js on the server side ? – mastodon Nov 28 '10 at 00:54
  • not on the server side, but on a document located on the 'receiving' domain. But no, you either need this, or use a flash/activex proxy etc - easyXDM is easier. – Sean Kinsey Nov 28 '10 at 10:32
  • Have you used it ? I'm not sure if I get it right. I can see at least 4 documents there. One - consumer - that performs the upload and it's stored locally. Second upload_rpc.html on remote server. I'm not sure how it is connected with the actual upload address. Then local 'name.html' and remote 'name.html' which I'm not sure what are for. – mastodon Nov 28 '10 at 15:21
  • I'm the developer. You can skip name.html unless you need to support some really old browsers. upload_rpc.html is the XDM endpoint that is responsible for relaying the response back and 'hosts' the iframe which is the target of the upload form. The form post action then use `parent.foo` to pass the response back to the original document. – Sean Kinsey Nov 28 '10 at 21:26
  • so let me check if I got it straight - my consumer's form posts to `upload url`, with the specified target iframe being in `upload_rpc.html`. After upload I'm getting back my result. I have two more questions - how the code in `upload_rpc` knows the result of upload ? And secondly do I get the iframe returned or just the rpc response ? I'm especially interested in the remote server sidesteps I need to take to get it going since I've got really limited access there and it would be best if I did it in a single try. – mastodon Nov 28 '10 at 22:36
  • oh one more thing - I don't create an iframe on client side right ? – mastodon Nov 28 '10 at 22:37
  • No, easyXDM creates the the iframe holding the provider which in turn contains the target iframe. – Sean Kinsey Nov 29 '10 at 21:21
  • @Sean Kinsey - really great lib this easyXDM! +1 – Luca Filosofi Dec 02 '10 at 20:08
1

Sean's easyXDM recommendation is a great option (& should probably be marked as correct), but I wanted to suggest another light-weight solution that I haven't seen anyone use.

In cases where you're posting to a hidden iframe on another domain & just need a single response back (not two-way communcation), you could pass a message from the iframe to the parent using a busted url. Here's an example:

  1. the parent loads an iframe on different domain

  2. the parent polls myframe.contentWindow.location.href (constantly getting Permission denied errors since the frame is on another domain)

  3. iframe processes, then redirects to

    http://parentdomain.com/pagethatdoesnotexist?{'result':'ok'}
    
  4. iframe gets a 404 but now the location is available to the parent

  5. the parent reads the message from the iframe's URL
bendytree
  • 13,095
  • 11
  • 75
  • 91
0

dont use .html() at all.

I used

jQuery('.someElement')

and it worked for me. you can save the result in a variable and insert it in new element

e.g

var = jQuery('.someElement');
jQuery('.newElement').html(var);
Natalie Rey
  • 51
  • 1
  • 3
0

one possible solution could be to set the name of the iframe with pure js. This name could be read from the wrapping parent page.

scheffield
  • 6,618
  • 2
  • 30
  • 31
0

Looks to me that your code will request uploadURL twice: first, .submit() do a POST request to upload the file and the result is shown in the iframe as a webpage; second, .getJSON() do a GET request and the result is executed as javascript in <script>. You will realize this if you open up Firebug while testing your app.

Since two of the requests are independent, I have no idea how .getJSON() will give you any information about the file you just uploaded with .submit().

For these kind of cross-domain communication, I would suggest using postMessage; otherwise you will need to change you application workflow to do everything in the iframe after file have uploaded; e.g. do <script>alert('Submission accepted');</script> in the iframe.

What are you trying to do after a user have successfully upload a file?

timdream
  • 5,914
  • 5
  • 21
  • 24
  • And is the db connect to the domain of `uploadURL`(A) or the domain the user is on (B)? Consider add the record directly on server side of (A) to db coz there is a change user might firing add record request to (B) without actually upload files to (A). – timdream Nov 27 '10 at 17:26
  • db is on local domain (B) and upload at (A). That's why I'm getting response from server after successful upload. Response is shown in iframe. So I want to read it out and if 'response' == 'true' add a new instance to my db. – mastodon Nov 27 '10 at 17:35
  • Then your should use `postMessage` to do pass information from the uploaded result in iframe to its parent. You might want to establish some shared secret between (a) and (b) to make sure the add record request is really legit. – timdream Nov 27 '10 at 17:40
  • So where I should place the script with pm, inside the iframe, on upload server, locally ? – mastodon Nov 27 '10 at 17:46
  • Yes. send the message from iframe on domain (b), listen for the message at the parent page on domain (a), send the db data along with the message to (a); check the message using the shared secret between (a) and (b). – timdream Nov 27 '10 at 17:51
  • problem is I cannot add record on `a` server since it's only used to serve statics so I need to send form to `a`, and then `a` returns response in iframe to `b`. So `b` needs to read out the status and basing on it either add a record or (refresh form)/(retry upload). – mastodon Nov 27 '10 at 17:57