You found a bug! We've classified it as EXTJS-5799 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #1
    Ext JS Premium Member rstuart's Avatar
    Join Date
    Jan 2008
    Location
    Brisbane, Australia
    Posts
    140
    Vote Rating
    4
    rstuart is on a distinguished road

      0  

    Question Does the CORS option in Ext.data.Connection v4.0.7 actually work?

    Does the CORS option in Ext.data.Connection v4.0.7 actually work?


    It is clear the code was never tested as it has a basic error (Uses Ext.isIe instead of Ext.isIE), but if I manually fix that is it actually useable? My tests indicate that answer is no so-far.

    Code:
            Ext.isIe = Ext.isIE;
            Ext.Ajax.request({
                method: 'GET',
                cors: true,
                params: {
                    format: 'json'
                },
                url: 'http://some.random.domain/restaurants',
                success: function(response) {
                    var results = Ext.decode(response.responseText);
                    Str.Restaurant = results['Restaurants'][0];
                    Str.store.RestaurantLocations.loadData(Str.Restaurant['Locations']);
                    Str.restaurantPanel.update(Str.Restaurant);
                    win.show();
                    myMask.hide();
                },
                failure: function(response) {
                    myMask.hide();
                    Ext.Msg.show({
                        title: 'Booking Time Error',
                        msg: 'There was an error fetching the Restaurants from the server.\n\nReservation system won\'t be available.',
                        buttons: Ext.Msg.OK,
                        icon: Ext.Msg.ERROR
                    });
                }
            });
        });
    The success handler is never called. Instead, the request times out and the failure is called. This is despite the developer tools in IE9 showing the request succeeded. Does this feature work?

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    36,555
    Vote Rating
    814
    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


    That is a bug and has been fixed in 4.1.0 beta 3 but I can confirm that it does work when that is fixed.
    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.

  3. #3
    Ext JS Premium Member rstuart's Avatar
    Join Date
    Jan 2008
    Location
    Brisbane, Australia
    Posts
    140
    Vote Rating
    4
    rstuart is on a distinguished road

      0  

    Question


    Every indication I have is that even in beta3 it doesn't work. My failure still gets run in IE9 after the CORS request succeeds. There are no JavaScript errors and the request works in Firefox, Chrome and Safari. Even this simple example fails in IE:

    Code:
            Ext.onReady(function() {
                Ext.Ajax.request({
                    method: 'GET',
                    cors: true,
                    params: {
                        format: 'json'
                    },
                    url: 'http://xxxx:9200/restaurants/101',
                    success: function(response) {
                        alert('success');
                    },
                    failure: function(response) {
                        alert('failed');
                    }
                });
            });
    In Firefox, Safari and Chrome this gets an alert that says "success" almost immediately. In IE9, it gets a "failed" after a decent delay. You can see this example running on a live site with a CORS compatible URL here.

    Has this definitely been tested and is definitely working?

  4. #4
    Ext JS Premium Member rstuart's Avatar
    Join Date
    Jan 2008
    Location
    Brisbane, Australia
    Posts
    140
    Vote Rating
    4
    rstuart is on a distinguished road

      0  

    Exclamation


    To say that I am a little frustrated right now is an understatement. This code was obviously never tested - EVER - because it will just plain not work for IE.

    Line 52310 of ext-all-sandbox-debug-w-comments.js of 4.1beta3 reads as follows:

    Code:
    xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me, [request]);
    The XDomainRequest object used by Microsoft doesn't have such an event. It's events are onerror, onload, onprogress and ontimeout as described here. THIS CODE COULD NEVER OF WORKED!

    Is it any wonder that the current state of ExtJS 4 is in complete disarray. First you use Ext.isIe instead of Ext.isIE, then you are trying to bind to events that don't even EXIST!This is basic stuff! Just testing this code once will have shown this error. Seriously, JUST ONCE!

    If there is code like this in such a core part of the framework that has not been run or tested then it begs the question what else is hiding in ExtJS 4? It begs an even bigger question of me - how was I tricked into paying for this.

  5. #5
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,509
    Vote Rating
    374
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    Do you want me to move this thread to Bugs so that developers can fix it before the Ext 4.1 final is out?
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid Search Plugin, ExtJS 5 Complex Data Binding using MVVM


  6. #6
    Ext JS Premium Member rstuart's Avatar
    Join Date
    Jan 2008
    Location
    Brisbane, Australia
    Posts
    140
    Vote Rating
    4
    rstuart is on a distinguished road

      0  

    Default


    If you think there is any chance that it will be fixed by 4.1 then yeah, go for it.

  7. #7
    Ext JS Premium Member rstuart's Avatar
    Join Date
    Jan 2008
    Location
    Brisbane, Australia
    Posts
    140
    Vote Rating
    4
    rstuart is on a distinguished road

      0  

    Default A workaround

    A workaround


    I have written some code that works for me in IE9 (a simple get and post request) but might not be complete. It certainly hasn't been tested as much as it needs to be on enough scenarios (but has been tested more then once!).

    It works by changing how the onStateChange method is bound to the xhr object and changing a line in the createResponse method that calls getAllResponseHeaders which doesn't exist on XDomainRequest. This is a band-aid fix. I suspect the real solution is to create a new object which wraps XDoimanRequest and XMLHttpRequest to give one unified object that can be used.

    Alternatively, abstracting the onComplete function slightly so that it takes a response code plus whatever else it needs instead of a request object directly would also work.

    Code:
    Ext.override(Ext.data.Connection, {
        request: function(options) {
            options = options || {};
            var me = this,
                scope = options.scope || window,
                username = options.username || me.username,
                password = options.password || me.password || '',
                async,
                requestOptions,
                request,
                headers,
                xhr;
    
    
            if (me.fireEvent('beforerequest', me, options) !== false) {
    
    
                requestOptions = me.setOptions(options, scope);
    
    
                if (me.isFormUpload(options)) {
                    me.upload(options.form, requestOptions.url, requestOptions.data, options);
                    return null;
                }
    
    
                // if autoabort is set, cancel the current transactions
                if (options.autoAbort || me.autoAbort) {
                    me.abort();
                }
    
    
                // create a connection object
                async = options.async !== false ? (options.async || me.async) : false;
                xhr = me.openRequest(options, requestOptions, async, username, password);
    
    
                headers = me.setupHeaders(xhr, options, requestOptions.data, requestOptions.params);
    
    
                // create the transaction object
                request = {
                    id: ++Ext.data.Connection.requestId,
                    xhr: xhr,
                    headers: headers,
                    options: options,
                    async: async,
                    timeout: setTimeout(function() {
                        request.timedout = true;
                        me.abort(request);
                    }, options.timeout || me.timeout)
                };
                me.requests[request.id] = request;
                me.latestId = request.id;
    
    
                // bind our statechange listener to the correct events
                if (async) {
                    if ((options.cors || me.cors) && Ext.isIE && Ext.ieVersion >= 8) {
                        // IE's XDomainRequest object doesn't have a onreadystatechange event
                        xhr.onerror = Ext.Function.bind(function(request) {
                            // No status object in Microsoft's implementation
                            request.xhr.status = 400;
                            this.clearTimeout(request);
                            this.onComplete(request);
                            this.cleanup(request);
                        }, me, [request]);
                        xhr.ontimeout = Ext.Function.bind(function(request) {
                            // No status object in Microsoft's implementation
                            request.xhr.status = 408;
                            this.clearTimeout(request);
                            this.onComplete(request);
                            this.cleanup(request);
                        }, me, [request]);
                        xhr.onload = Ext.Function.bind(function(request) {
                            // No status object in Microsoft's implementation
                            request.xhr.status = 200;
                            this.clearTimeout(request);
                            this.onComplete(request);
                            this.cleanup(request);
                        }, me, [request]);
                    } else {
                        xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me, [request]);
                    }
                }
    
    
                // start the request!
                xhr.send(requestOptions.data);
                if (!async) {
                    return me.onComplete(request);
                }
                return request;
            } else {
                Ext.callback(options.callback, options.scope, [options, undefined, undefined]);
                return null;
            }
        },
        createResponse : function(request) {
            var xhr = request.xhr,
                headers = {},
                // IE's XDomainRequest has no method getAllResponseHeaders. Thanks Microsoft - no really thanks.
                lines = xhr.getAllResponseHeaders !== undefined ? xhr.getAllResponseHeaders.replace(/\r\n/g, '\n').split('\n') : '',
                count = lines.length,
                line, index, key, value, response;
    
    
            while (count--) {
                line = lines[count];
                index = line.indexOf(':');
                if (index >= 0) {
                    key = line.substr(0, index).toLowerCase();
                    if (line.charAt(index + 1) == ' ') {
                        ++index;
                    }
                    headers[key] = line.substr(index + 1);
                }
            }
    
    
            request.xhr = null;
            delete request.xhr;
    
    
            response = {
                request: request,
                requestId : request.id,
                status : xhr.status,
                statusText : xhr.statusText,
                getResponseHeader : function(header) {
                    return headers[header.toLowerCase()];
                },
                getAllResponseHeaders : function() {
                    return headers;
                },
                responseText : xhr.responseText,
                responseXML : xhr.responseXML
            };
    
    
            // If we don't explicitly tear down the xhr reference, IE6/IE7 will hold this in the closure of the
            // functions created with getResponseHeader/getAllResponseHeaders
            xhr = null;
            return response;
        }
    });
    Bottom line is that XDomainRequest sucks and, by association, so does Microsoft.

  8. #8
    Ext JS Premium Member rstuart's Avatar
    Join Date
    Jan 2008
    Location
    Brisbane, Australia
    Posts
    140
    Vote Rating
    4
    rstuart is on a distinguished road

      0  

    Question


    This bug still doesn't have an issue number. Has it been accepted?

  9. #9
    Sencha User
    Join Date
    May 2012
    Posts
    10
    Vote Rating
    1
    geron is on a distinguished road

      1  

    Default CORS does not work at all in ExtJS 4.0.7

    CORS does not work at all in ExtJS 4.0.7


    I just found out, that CORS does not work at all in ExtJS 4.0.7, i.e. it is not only a problem with IE...
    Here is what I tried as a direct comparison between ExtJS and XMLHttpRequest:

    The following file is served as xyz.html from my local apache web server. It is going to make a REST call to another web server (see urlx). The first call with XMLHttpRequest is successful and the second fails

    -------------------------------------------------------------
    <!-- xyz.html
    a simple CORS test
    showing that XMLHttpRequest works and ExtJS.Ajax.request fails!
    -->


    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>cors test</title>
    <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-4.0.7-commercial/resources/css/ext-all.css"/>
    <script type="text/javascript" src="http://extjs.cachefly.net/ext-4.0.7-commercial/ext-all-debug.js"></script>
    <script type="text/javascript">


    // plain XMLHttpRequest - works!
    var urlx = "http://server2/services";
    var bodyx = "welcome at home";
    var client = new XMLHttpRequest();
    client.open("GET", urlx, false);
    client.setRequestHeader("Content-Type", "text/plain");
    client.send(bodyx);
    if (client.status == 200)
    console.log('XMLHttpRequest, cross domain request: success!');
    else
    console.log('XMLHttpRequest, cross domain request: failure!');

    // ExtJS test - does not work!
    Ext.Ajax.request({
    url: urlx,
    method: 'GET',
    cors: true,
    success: function(response) {
    console.log('ExtJS.Ajax, cross domain request: success!');
    },
    failure: function(response) {
    console.log('ExtJS.Ajax, cross domain request: failure!');
    }
    });
    </script>
    </head>
    <body></body>
    </html>
    ---------------------------------------------------

  10. #10
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    36,555
    Vote Rating
    814
    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


    With 4.1.1 I used this code:

    Code:
    Ext.Ajax.request({
        url      : 'http://test/data/php.php',
        callback : function(options, success, response) {
            console.log(response.responseText);
        }
    });
    And it worked for me:

    Screen Shot 2012-08-06 at 4.10.02 PM.png
    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.