1. #1
    Sencha Premium Member
    Join Date
    Aug 2012
    Posts
    43
    Answers
    2
    Vote Rating
    0
    bjnelson62 is on a distinguished road

      0  

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

    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 - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,412
    Answers
    3549
    Vote Rating
    850
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    What does the request actually look?
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  4. #3
    Sencha Premium Member
    Join Date
    Aug 2012
    Posts
    43
    Answers
    2
    Vote Rating
    0
    bjnelson62 is on a distinguished road

      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
    bjnelson62 is on a distinguished road

      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
    bjnelson62 is on a distinguished road

      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
    bjnelson62 is on a distinguished road

      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

Thread Participants: 1