Results 1 to 6 of 6

Thread: Upload binary file using form.submit()

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Sencha Premium Member
    Join Date
    Aug 2012
    Posts
    43
    Answers
    2
    Vote Rating
    0
      0  

    Default Answered: Upload binary file using form.submit()

    I've got a form that has combo and filefield controls. When the user clicks Upload, the following code is executed:

    Code:
                            form.submit({
                                url: myUrl,
                                headers: {'Content-Type':'multipart/mixed; charset=UTF-8'},
                                params: {
                                    metadata: {'version' : '2.8.1.RELEASE'},
                                },
                                waitMsg: 'Uploading your image....',
                                success: function(form, action) {
                                    VFABRIC.util.StatusBarWrapper.setGoodStatus('Successfully uploaded file: ' + action.result.file);
                                },
                                failure: function(form, action) {
                                    switch (action.failureType) {
                                        case Ext.form.action.Action.CLIENT_INVALID:
                                            VFABRIC.util.StatusBarWrapper.setErrorStatus('Form fields may not be submitted with invalid values');
                                            break;
                                        case Ext.form.action.Action.CONNECT_FAILURE:
                                            VFABRIC.util.StatusBarWrapper.setErrorStatus('Ajax communication failed');
                                            break;
                                        case Ext.form.action.Action.SERVER_INVALID:
                                            VFABRIC.util.StatusBarWrapper.setErrorStatus(VFABRIC.util.AjaxWrapper.getServerErrorMsgs(action.response));
                                            break;
                                    }
                                    me.up('window').destroy();
                                },
                            });
    The server is unhappy, because it wants a metadata field. I tried to specify it in the code above, but obviously I'm not doing it correctly. Here's how the request should look:


    POST /<product name>/v1/installation-images/
    Content-Type: multipart/mixed; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
    --6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
    Content-Disposition: form-data; name="metadata"
    Content-Type: application/json;charset=UTF-8

    {"version":"2.7.0.RELEASE"}
    --6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
    Content-Disposition: form-data; name="data"; filename="installation-image.zip"
    Content-Type: application/octet-stream
    Content-Length: 7340032

    <binary data>
    --6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm--


    Any ideas as to how I could structure the request to make the server happy? I know how the request should look, but I don't know how to achieve that look through the ExtJs library.

    Is this even possible? I thought of using the Ext.Ajax() class directly, but then I run into the problem of not knowing the filename because the browser won't report it to the filefield control.

    Thank you,

    Brian

  2. So far as I know, there's no way to do this in ExtJS. I found some comments that indicate request headers are ignored on a file upload, and that was my experience too.

    So instead I resorted to calling XMLHttpRequest. Also, I used FormData to add in the version metadata.

    But I respectfully submit that anytime a customer has to go outside your framework to do something, you've failed. I know, I've worked on SCM systems in the past.

    Brian

  3. #2
    Sencha - Sr Software Engineer mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    39,553
    Answers
    3931
    Vote Rating
    1272
      0  

    Default

    What does the request actually look?
    Mitchell Simoens @LikelyMitch
    Sencha Inc, Senior Software Engineer
    ________________
    Learn BBCode and use it! Checkout the CODE tag!

    Check out my GitHub, lots of nice things for Ext JS and Sencha Touch
    https://github.com/mitchellsimoens

  4. #3
    Sencha Premium Member
    Join Date
    Aug 2012
    Posts
    43
    Answers
    2
    Vote Rating
    0
      0  

    Default

    What I posted earlier is exactly how the request should look; I didn't put it in the code brackets because technically it's not code, but I'll post it again:

    Code:
    POST /<product name>/v1/installation-images/
    Content-Type: multipart/mixed; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
    --6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
    Content-Disposition: form-data; name="metadata"
    Content-Type: application/json;charset=UTF-8
    
    {"version":"2.7.0.RELEASE"}
    --6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
    Content-Disposition: form-data; name="data"; filename="installation-image.zip"
    Content-Type: application/octet-stream
    Content-Length: 7340032
    
    <binary data>
    --6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm--
    My biggest issue (right now, don't know if there's another lurking beyond) is how to do the METADATA part. I've tried, but what I've tried so far was not palatable by the server.

    Thanks,

  5. #4
    Sencha Premium Member
    Join Date
    Aug 2012
    Posts
    43
    Answers
    2
    Vote Rating
    0
      0  

    Default

    Another way to express this is, is it possible to set the request headers on a form submission? So far I've been unsuccessful. In addition to what I already posted, I also tried this:

    Code:
                            var boundary = '6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm',
                                parts = new Array();
    
                                parts.push('Content-Type: multipart/mixed; boundary=' + boundary);
                                parts.push('--' + boundary);
                                parts.push('Content-Disposition: form-data; name="metadata"');
                                parts.push('Content-Type: application/json;charset=UTF-8');
                                parts.push('{"version":"2.8.1.RELEASE"}');
                                parts.push('--' + boundary);
                                parts.push('Content-Disposition: form-data; name="data"; filename="installation-image.zip"');
                                parts.push('Content-Type: application/octet-stream');
                                parts.push('Content-Length: 7340032');
                                parts.push('--' + boundary);
                            
                            form.submit({
                                url: myUrl,
                                headers: parts, //{'Content-Type':'multipart/mixed; charset=UTF-8'},
    /*
                                params: {
                                    metadata: {'version' : '2.8.1.RELEASE'},
                                },
    */
                                waitMsg: 'Uploading your image....',
                                success: function(form, action) {
                                    me.up('window').destroy();
                                    VFABRIC.util.StatusBarWrapper.setGoodStatus('Successfully uploaded file: ' + action.result.file);
                                },
                                failure: function(form, action) {
                                    me.up('window').destroy();
                                    switch (action.failureType) {
                                        case Ext.form.action.Action.CLIENT_INVALID:
                                            VFABRIC.util.StatusBarWrapper.setErrorStatus('Form fields may not be submitted with invalid values');
                                            break;
                                        case Ext.form.action.Action.CONNECT_FAILURE:
                                            VFABRIC.util.StatusBarWrapper.setErrorStatus('Ajax communication failed');
                                            break;
                                        case Ext.form.action.Action.SERVER_INVALID:
                                            VFABRIC.util.StatusBarWrapper.setErrorStatus(VFABRIC.util.AjaxWrapper.getServerErrorMsgs(action.response));
                                            break;
                                    }
                                },
                            });
    It appears the headers I specify are totally ignored, based on what I see in the Network tab.

    If this isn't possible, is there any other way I could do what I need to make the server happy? I'd prefer an Ext solution, but I'll accept a third party way (or rolling my own).

  6. #5
    Sencha Premium Member
    Join Date
    Aug 2012
    Posts
    43
    Answers
    2
    Vote Rating
    0
      0  

    Default

    I found comments that indicate that headers are ignored when uploading a file. This should really be documented, it's crazy for developers (I'm not the only one) to be wasting time trying to get something to work that never will.

    Is there any other way within Ext to get this to work? What are the third party options, if any?

  7. #6
    Sencha Premium Member
    Join Date
    Aug 2012
    Posts
    43
    Answers
    2
    Vote Rating
    0
      0  

    Default

    So far as I know, there's no way to do this in ExtJS. I found some comments that indicate request headers are ignored on a file upload, and that was my experience too.

    So instead I resorted to calling XMLHttpRequest. Also, I used FormData to add in the version metadata.

    But I respectfully submit that anytime a customer has to go outside your framework to do something, you've failed. I know, I've worked on SCM systems in the past.

    Brian

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •