Newsgroup: it.comp.lang.javascript
Titolo: Eseguire il parse di richiesta POST e IE

In un'applicazione javascript mi e` capitato di dover inserire l'upload
di un file, da quello che ho letto il modo migliore per fare questo tipo
di operazione e` creare un nuovo iframe invisibile target
dell'operazione in quanto un elemento input di tipo file deve
necessariamente generare dell'html come output.
La cosa mi funziona, peccato solo che il mio webserver risponda
all'upload con un xml, che leggo nell'iframe nascosto,  che viene
deturpato orrendamente in quanto interpretato da explorer come html (con 
firefox funziona)....
Sull'iframe target nascosto in pratica ho un metodo onload che mi va a 
invocare la callback di "completamento".
In questa callback faccio quello suggerito su molti siti (tra cui 
http://developer.apple.com/internet/webcontent/iframe.html
):
loaded : function(id) {
   var i = document.getElementById(id);
   var d;
   if (i.contentDocument) {
     d = i.contentDocument;
   } else if (i.contentWindow) {
     d = i.contentWindow.document;
   } else {
     d = window.frames[id].document;
   }
   if (d.location.href == "about:blank") {
     return;
   }
   if (typeof(i.onComplete) == 'function') {
     i.onComplete(d);
   }
}
Firefox trova contentDocument, explorer trova contentWindow.
Purtroppo contentWindow.document contiene gia` un parse HTML del mio XML 
(con cose tipo <STYLE> {font:x-small "Verdana'; } </STYLE> dentro)... da 
cui non riesco a tornare all'XML originale...
Ho il controllo totale della risposta alla richiesta POST generabile dal 
server, penso di inviare correttamente la richiesta, ecco un dump:
------------ CUT -------------
HTTP/1.0 200 OK
Server: DARTSHttpd/0.1
Content-Type: text/xml
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<AddVboxVersionResp>
<result>KO</result>
<reason>Il file non e` un pacchetto installer</reason>
<errcode>7</errcode>
</AddVboxVersionResp>
------------ CUT -------------
In genere, tramite i classici request GET, IE e` perfettamente in grado 
di parsare questo tipo di risposte...

 necessariamente generare dell'html come output.
Ebbi un problema simile e lo risolsi con un plugin di jquery che si
chiama jquery.form.js
all'interno del plugin si osserva la funzione apposita, la posto qui
per tua utilità.
    function fileUpload() {
        var form = $form[0];
        if ($(':input[@name=submit]', form).length) {
            alert('Error: Form elements must not be named "submit".');
            return;
        }
        var opts = $.extend({}, $.ajaxSettings, options);
        var id = 'jqFormIO' + (new Date().getTime());
        var $io = $('<iframe id="' + id + '" name="' + id + '" />');
        var io = $io[0];
        if ($.browser.msie || $.browser.opera)
            io.src = 'javascript:false;document.write("");';
        $io.css({ position: 'absolute', top: '-1000px', left:
'-1000px' });
        var xhr = { // mock object
            responseText: null,
            responseXML: null,
            status: 0,
            statusText: 'n/a',
            getAllResponseHeaders: function() {},
            getResponseHeader: function() {},
            setRequestHeader: function() {}
        };
        var g = opts.global;
        // trigger ajax global events so that activity/block
indicators work like normal
        if (g && ! $.active++) $.event.trigger("ajaxStart");
        if (g) $.event.trigger("ajaxSend", [xhr, opts]);
        var cbInvoked = 0;
        var timedOut = 0;
        // add submitting element to data if we know it
        var sub = form.clk;
        if (sub) {
            var n = 
sub.name
;
            if (n && !sub.disabled) {
                options.extraData = options.extraData || {};
                options.extraData[n] = sub.value;
                if (sub.type == "image") {
                    options.extraData[name+'.x'] = form.clk_x;
                    options.extraData[name+'.y'] = form.clk_y;
                }
            }
        }
        // take a breath so that pending repaints get some cpu time
before the upload starts
        setTimeout(function() {
            // make sure form attrs are set
            var t = $form.attr('target'), a = $form.attr('action');
            $form.attr({
                target:   id,
                encoding: 'multipart/form-data',
                enctype:  'multipart/form-data',
                method:   'POST',
                action:   opts.url
            });
            // support timout
            if (opts.timeout)
                setTimeout(function() { timedOut = true; cb(); },
opts.timeout);
            // add "extra" data to form if provided in options
            var extraInputs = [];
            try {
                if (options.extraData)
                    for (var n in options.extraData)
                        extraInputs.push(
                            $('<input type="hidden" name="'+n+'"
value="'+options.extraData[n]+'" />')
                                .appendTo(form)[0]);
                // add iframe to doc and submit the form
                $io.appendTo('body');
                io.attachEvent ? io.attachEvent('onload', cb) :
io.addEventListener('load', cb, false);
                form.submit();
            }
            finally {
                // reset attrs and remove "extra" input elements
                $form.attr('action', a);
                t ? $form.attr('target', t) : $form.removeAttr
('target');
                $(extraInputs).remove();
            }
        }, 10);
        function cb() {
            if (cbInvoked++) return;
            io.detachEvent ? io.detachEvent('onload', cb) :
io.removeEventListener('load', cb, false);
            var operaHack = 0;
            var ok = true;
            try {
                if (timedOut) throw 'timeout';
                // extract the server response from the iframe
                var data, doc;
                doc = io.contentWindow ? io.contentWindow.document :
io.contentDocument ? io.contentDocument : io.document;
                if (doc.body == null && !operaHack && $.browser.opera)
{
                    // In Opera 9.2.x the iframe DOM is not always
traversable when
                    // the onload callback fires so we give Opera
100ms to right itself
                    operaHack = 1;
                    cbInvoked--;
                    setTimeout(cb, 100);
                    return;
                }
                xhr.responseText = doc.body ? doc.body.innerHTML :
null;
                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument :
doc;
                xhr.getResponseHeader = function(header){
                    var headers = {'content-type': opts.dataType};
                    return headers[header];
                };
                if (opts.dataType == 'json' || opts.dataType ==
'script') {
                    var ta = doc.getElementsByTagName('textarea')[0];
                    xhr.responseText = ta ? ta.value :
xhr.responseText;
                }
                else if (opts.dataType == 'xml' && !xhr.responseXML &&
xhr.responseText != null) {
                    xhr.responseXML = toXml(xhr.responseText);
                }
                data = $.httpData(xhr, opts.dataType);
            }
            catch(e){
                ok = false;
                $.handleError(opts, xhr, 'error', e);
            }
            // ordering of these callbacks/triggers is odd, but that's
how $.ajax does it
            if (ok) {
                opts.success(data, 'success');
                if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
            }
            if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
            if (g && ! --$.active) $.event.trigger("ajaxStop");
            if (opts.complete) opts.complete(xhr, ok ? 'success' :
'error');
            // clean up
            setTimeout(function() {
                $io.remove();
                xhr.responseXML = null;
            }, 100);
        };
        function toXml(s, doc) {
            if (window.ActiveXObject) {
                doc = new ActiveXObject('Microsoft.XMLDOM');
                doc.async = 'false';
                doc.loadXML(s);
            }
            else
                doc = (new DOMParser()).parseFromString(s, 'text/
xml');
            return (doc && doc.documentElement &&
doc.documentElement.tagName != 'parsererror') ? doc : null;
        };
    };

 server, penso di inviare correttamente la richiesta, ecco un dump:
Si, non � quello il problema. La richiesta la invii correttamente.
Il fatto � che IE modifica l'XML per renderlo leggibile.
Una possibile soluzione, che non funziona su versioni di IE<6, pu�
essere quella di aggiungere uno stylesheet XSLT al tuo XML.
In questo modo, IE utilizzer� quello stylesheet per trasformare il
tuo XML invece che quello di default. Attento per� che questo vien
fatto anche dagli altri browser.
Oppure invece che text/xml imposta text/plain o text/html.
-- 
"When you have eliminated the impossible, whatever remains, however
improbable, must be the truth."