Thank you for reporting this bug. We will make it our priority to review this report.
  1. #1
    Sencha User
    Join Date
    Oct 2009
    Location
    Cambridge, UK
    Posts
    164
    Vote Rating
    0
    Uberdude is on a distinguished road

      0  

    Default Response lost from upload Ajax request to iframe if document.domain changed

    Response lost from upload Ajax request to iframe if document.domain changed


    Ext version tested:
    • Ext 3.3.0

    Adapter used:
    • ext

    css used:
    • default ext-all.css
    • optionally examples.css from Ext examples to make test case look nice, but this is not a UI issue.

    Browser versions tested against:
    • Chrome 10.0.648.204
    • IE9, IE7
    • FF 3.6.15 (firebug 1.7.1 installed)
    • Opera 11.01
    • Safari 5.0.3 (7533.19.4)

    Operating System:
    • Windows 7 64-bit for all browsers except IE7
    • Windows Server 2003 for IE7

    Description:

    When you make an Ext.Ajax.request with a form containing a file input to be uploaded, or manually set the isUpload option to true, rather than doing a proper Ajax request Ext submits the form in the standard HTML way to a dynamically generated hidden <iframe>. The json response body is then read out of the iframe to create a faked-up Ajax response. A problem arises if the page making the upload Ajax request has changed its document.domain property, e.g. a page at home.example.com includes resources from static.example.com which it wishes to manipulate with javascript without violating the browser's same-origin-policy, so both set their document.domain to "example.com". If home.example.com then makes an upload Ajax request to a url on the home.example.com server, the iframe into which the response is written will have its document.domain as "home.example.com". Thus when the ExtJS code within Ajax.request on the home.example.com page tries to extract the document body from the iframe, it will be blocked by the same-origin-policy and the response passed to the callback functions will incorrectly have empty responseText.

    Test Case:

    Code:
    <html>
    <head>
        <title>Upload Form to iFrame with changed document.domain</title>
    
        <!-- TODO update these paths for your environment, they are currently based on this file being in the Ext examples/form directory -->
    
        <!-- ** CSS ** -->
        <!-- base library -->
        <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css"/>
    
        <!-- overrides to base library -->
        <!-- page specific, just to make it pretty, no big deal if missing -->
        <link rel="stylesheet" type="text/css" href="../shared/examples.css" />
    
        <!-- ** Javascript ** -->
        <!-- base library -->
        <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
        <script type="text/javascript" src="../../ext-all.js"></script>
    
    </head>
    <body>
        <h1>File Upload to iFrame with changed document.domain</h1>
        <p>The example demonstrates how shortening the document.domain causes the response from file-upload-style Ajax requests to get lost.</p>
        <p>To run this test you need to deploy it to a real web server rather than run from local file system (so that document.domain is not blank) and the server should have a urls <b>welcomeAjax</b> and <b>welcomeUpload</b>.</p>
        
        <p>The current value of document.domain is: </p>
        <div id="domainText"></div>    
        <br>
        
        <div id="trimBtn"></div>
        <br>
        
        <div id="welcomeForm"></div>
     
        <script type="text/javascript"> 
        
            Ext.BLANK_IMAGE_URL = '../../resources/images/default/s.gif';
    
            Ext.onReady(function() {
            
                var domainText = new Ext.form.TextField({
                    readOnly: true,
                    renderTo: 'domainText',
                    width: 300
                });
                
                function displayDomain() {
                    domainText.setValue(document.domain);
                }
                displayDomain();
                
                new Ext.Button({
                    renderTo: 'trimBtn',
                    text: 'Trim Domain',
                    handler: function() {
                        document.domain = document.domain.substr(document.domain.indexOf('.') + 1);
                        displayDomain();                    
                    }
                });
                var welcomeForm = new Ext.form.FormPanel({
                    bodyStyle: 'padding: 5px;',        
                    buttonAlign:'center',
                    renderTo: 'welcomeForm',
                    title: 'Welcome Form',
                    width: 300,
                    height: 100,
                    items: [{
                        fieldLabel: 'Name',
                        name: 'name',
                        xtype: 'textfield'
                    }],
                    buttons: [
                        {
                            text: 'Submit with Normal Ajax',
                            handler: function() {
                                makeRequest();
                            }
                        }, {
                            text: 'Submit with File Upload',
                            handler: function() {
                                makeRequest(true);
                            }
                        }
                    ]
                });
    
                function makeRequest(upload) {
                    Ext.Ajax.request({
                        url: upload ? '../welcomeUpload' : '../welcomeAjax',          // TODO Adjust these for your server
                        form: welcomeForm.getForm().getEl(),
                        isUpload: upload,
                        success: function(response) {
                            if (!response) {
                                Ext.Msg.alert('Success?', 'No response');
                            }
                            else if (!response.responseText) {
                                Ext.Msg.alert('Success?', 'Response but empty responseText, this is the symptom of the domain bug!');
                            }
                            else {
                                Ext.Msg.alert('Success', Ext.decode(response.responseText).msg);
                            }
                        },
                        failure: function() {
                            Ext.Msg.alert('Error', 'Generic fail');
                        }
                    });
                }
            });
        </script>
    </body>
    </html>
    As this issue relates to document.domain, you need to deploy this file to a real webserver, preferably with a sub-domain as in "foo.bar.com" so the document.domain can be set to "bar.com". If you have just a domain "foo.com", setting the domain to "com" is dodgy.

    The webserver also needs 2 urls to provide json respones, presented below in nodeJS code, adapt this to whatever server technology you use.

    Code:
    // In our nodeJS framework this is how we make controller methods
    exports.handlers = {
        welcomeAjax: {
            handler: function(params, response) {
                response.setHeader('Content-Type', 'application/json');
                // Write json and end
                response.end(JSON.stringify({msg: 'Welcome ' + params.name}));
            }
        },
        
        welcomeUpload: {
            handler: function(params, response) {
                // Note content type must be set to html for file uploads, not doing so is a common cause of errors and thus forum posts.
                response.setHeader('Content-Type', 'text/html');
                response.end(JSON.stringify({msg: 'Welcome ' + params.name}));
            }
        }
    };
    Steps to reproduce the problem:
    • Deploy the test harness html to your web server and create the server side urls to serve the json response.
    • On the page, type you name in the Name text box.
    • 1. Click Submit with Normal Ajax
    • 2. Click Submit with File Upload
    • 3. Click Trim Domain
    • 4. Click Submit with Normal Ajax
    • 5. Click Submit with File Upload


    The result that was expected:
    • 1. and 2. each cause a Welcome message box to appear
    • After 3. you see in the domain textbox that the domain has been shortened, e.g. from foo.bar.com to bar.com
    • 4. and 5. each cause a Welcome message box to appear

    The result that occurs instead:
    • 1. and 2. each cause a Welcome message box to appear
    • After 3. you see in the domain textbox that the domain has been shortened, e.g. from foo.bar.com to bar.com
    • 4. causes a Welcome message box to appear
    • 5. causes a message box with "Response but empty responseText, this is the symptom of the domain bug!" to appear. If you look in the Chrome debug console you will see an error message like "Unsafe JavaScript attempt to access frame with URL http://foo.bar.com/welcomeUpload from frame with URL http://foo.bar.com/upload-domain.html. Domains, protocols and ports must match."

    Debugging already done:
    • I have determined that it is the browser's same-origin-policy that means the parent page cannot access the document within the dynamic iframe that contains the response body. Inspecting the html of the page (using firebug, Chrome dev tools or equivalent) I can see the iframe and it does contain the response json.
    • The problem occurs on line 6543 of ext-all-debug.js in the doFormUpload function
      Code:
      doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;
      frame.contentWindow evaluates ok, but when trying to access the document property of the resulting object generates the access denied error. The 3 OR clauses here leads to 3 copies of the error in the console

    Possible fix:

    I tried hacking the Ext source code to set the document.domain of the <iframe> when it is constructed to be the same as that of the page creating it, but failed to do so. I have managed to workaround this problem by sending the document.domain as an extra parameter on all file upload requests, and then changing the server-side code to inject a script tag which sets the document.domain of the response html document containing the json to that specified in the parameter. But this is rather unpleasant and the ideal solution would be if somehow Ext JS could change the iframe's domain.

    My workaround comprises the following changes:

    We have a wrapper around Ext.Ajax.request which, similar to within Ext, can turn a params based request into a form upload one (but with added custom functionality)
    Code:
    // items are hidden form field config corresponding to the request parameters
    formPanel = new Ext.form.FormPanel({
        hidden: true,
        items: items,
        renderTo: Ext.getBody() // Have to add it to the DOM somewhere to get the <FORM>
    });
    
    args.isUpload = true;
    args.form = formPanel.getForm().getEl();
    Ext.Ajax.request(args);
    To the items is added an extra domain parameter:
    Code:
    items.push({
        name: '__domain',
        value: document.domain,
        xtype: 'hidden'
    });
    Then server-side the welcomeUpload handler changes to inject a script tag in the header (so the body is still just the json and can be used to reconstruct the fake XHR response):
    Code:
    welcomeUpload: {
        handler: function(params, response) {
            // Note content type must be set to html for file uploads, not doing so is a common cause of errors and thus forum posts.
            response.setHeader('Content-Type', 'text/html');
            response.write('<html><head><script type="text/javascript">document.domain = "' + params.__domain + '";</script></head><body>');
            response.write(JSON.stringify({msg: 'Welcome ' + params.name}));
            response.end('</body></html>');
        }
    }
    With this workaround applied, all 4 clicks in the test case cause the welcome message to appear.
    Last edited by Uberdude; 27 Jun 2011 at 1:12 AM. Reason: WIP!

  2. #2
    Sencha User
    Join Date
    Nov 2008
    Posts
    7
    Vote Rating
    0
    gknith is on a distinguished road

      0  

    Default documet.domain is not getting changed with script.

    documet.domain is not getting changed with script.


    documet.domain is not getting changed with script.

  3. #3
    Sencha User
    Join Date
    Mar 2012
    Location
    Sweden
    Posts
    1
    Vote Rating
    0
    torolsson is on a distinguished road

      0  

    Default Same problem

    Same problem


    I'm having the exact same problem. I'm ditching the document.domain solution I use in favor of a solution based on an iframe in the iframe, described here:
    http://stackoverflow.com/questions/1.../362564#362564

    Hopefully the Ext Core (3.1.0) fake-ajax-file-upload-form-post-iframe-problem will disapear!

    Since I have the need for a dynamic height setting on my iframe, I had to make some adjustments. I've described the in the same thread:
    http://stackoverflow.com/questions/153152/resizing-an-iframe-based-on-content/9796214#9796214

  4. #4
    Sencha User
    Join Date
    Oct 2009
    Location
    Cambridge, UK
    Posts
    164
    Vote Rating
    0
    Uberdude is on a distinguished road

      0  

    Default


    Sencha don't seem to care about Ext 3 anymore so I doubt anyone will look at or fix this bug. From looking at the Ext 4 source code it seems to suffer from the same bug, but I've not actually tried it out to make a test case and report in the Ext 4 bugs forum.

  5. #5
    Sencha User
    Join Date
    Jun 2012
    Posts
    1
    Vote Rating
    0
    dshapiro is on a distinguished road

      0  

    Default


    I have, and it does.

  6. #6
    Sencha Premium Member
    Join Date
    May 2013
    Posts
    25
    Vote Rating
    1
    dustyfrog is on a distinguished road

      0  

    Default


    Yes, same error occurs in ExtJS 4.2. Any plans to fix this problem?

film izle

hd film izle

film sitesi

takipci kazanma sitesi

takipci kazanma sitesi

güzel olan herşey

takipci alma sitesi

komik eğlenceli videolar