2012-01-30 13 views
6

Estoy luchando para que un webworker cargue un archivo XML desde el mismo dominio al costado de mi página principal, cualquier ayuda sería muy apreciada.JavaScript webworker no cargará archivos XML a través de XMLHttpRequest

function readXML(){ 
var xhr = new XMLHttpRequest(); //Only for FF 
xhr.open("GET","../db/pointer.xml",true); 
xhr.send(null); 
xhr.onreadystatechange = function(e){ 

if(xhr.status == 200 && xhr.readyState == 4){ 
    //Post back info to main page 
    postMessage(xhr.responseXML.getElementsByTagName("value").length); 
} 
} 

Cuando esto se ejecuta en una etiqueta de script en la página principal, aparece un 3. Cuando se ejecuta a través de la WebWorker, FireBug me da

hr.responseXML es nulo

postMessage (xhr.responseXML.getElementsByTagName ("value"). length);

En la consola de Firebug, GET Solicitud respondió con

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <value>A value</value> 
    <value>Another Value</value> 
    <value>A third Value</value> 
</root> 

Así que la respuesta es correcta, pero no puedo averiguar dónde va mal. si cambio responseXML a responseText las salidas de los trabajadores

Un valor Otro valor un tercer valor

Qué es lo correcto! ¿Por qué el guión no abrirá como un documento XML?

ACTUALIZACIÓN

function readXML(){ 
var xhr = new XMLHttpRequest(); //Only for FF 
xhr.open("GET","../db/pointer.xml",false); 
xmlhttp.setRequestHeader('Content-Type', 'text/xml'); 
xhr.overrideMimeType('text/xml'); 
xhr.send(null); 
xhr.onreadystatechange = function(e){ 

if(xhr.status == 200 && xhr.readyState == 4){ 
    //Post back info to main page 
    postMessage(xhr.responseXML.getElementsByTagName("value").length); 
} 
} 

Cuando se cambia setRequestHeader & overrideMimeType, la onreadystatechange nunca se dispara, no importa si el estado y readyState están allí o no, no va a funcionar. Si elimino el onreadystatechange por completo y simplemente ejecuto xhr.responseXML, recibo el error nulo de nuevo.

Todavía obtengo el XML correcto como respuesta en la consola, ¿se trata de un problema de webworker en lugar de un problema de httprequest? Desesperando aquí :)

index.html http://www.axlonline.se/worker/index.html
worker.js http://www.axlonline.se/worker/worker.js

Respuesta

-2

Sólo tiene que establecer el encabezado de tipo de contenido a text/xml en el lado del servidor. responseXML es nulo si el documento que está solicitando no es XML. Específicamente, el tipo de contenido debe ser uno de text/html, text/xml, application/xml, o algo que termine en +xml. Ver the spec.

Además, ver: responseXML is null y responseXML always null.

Y una nota al margen: dado que los trabajadores web son intrínsecamente asíncronos, no necesita establecer el indicador async en verdadero en su llamada open.

+0

Todavía no funciona después de que agregué requestheader e intenté anular el tipo de mime, responseXML sigue siendo nulo. Parece ser un problema con el webworker ya que los scripts funcionan bien en el documento principal. – axlOnline

+0

Tengo el mismo problema; tipo mime configurado en text/xml en script de respuesta, el estado listo xmlhttprequest es 4 y responseType está en blanco y responseXML es nulo. Frustrante. Una solución que he estado usando es traducir XML a JSON en PHP, y devolver eso, y usar JSON.parse, que afortunadamente sí funciona. –

3

De acuerdo con la norma, los trabajadores web no pueden tener acceso a ningún tipo de manipulación de DOM.

Las DOM API (objetos de nodo, objetos de documento, etc.) no están disponibles para los trabajadores en esta versión de esta especificación.

responseXML y las propiedades de canal siempre son nulas desde una solicitud ajax ya que el análisis del XML es una DOM API. Sin importar los encabezados de solicitud y respuesta, no habrá forma de obtener requestXML a menos que lo analice manualmente.

+1

JSON.parse, por otro lado, está disponible. Esto le permitiría cambiar el XML a JSON en el lado del servidor como dijo @Jon_Fournier – georgephillips

0

Tenía el mismo problema. Aparentemente, el análisis XML no es posible en los webworkers. Usé sax.js para analizar un XML en un trabajador web. https://github.com/isaacs/sax-js

esto es básicamente mi analizador.

function xmlParser(strict){ 
    this.parser = sax.parser(strict, {lowercase:true}); 
} 

xmlParser.prototype.parseFile = function(file, callback){ 
    var _this = this; 
    $.ajax.get({ 
     cache: false, 
     url: file, 
     dataType: "xml", 
     success: function(data){ 
      var dom = _this.parseText(data.text); 
      callback(dom); 
     }, 
     error: function(data){ 
     } 
    }); 
} 

xmlParser.prototype.parseText = function(xlmText){ 
    var dom = undefined; 
    var activeNode = dom; 

    this.parser.onerror = function (e) { }; 
    this.parser.onend = function() {}; 

    this.parser.ontext = function (t) { 
     if(activeNode != undefined) 
      activeNode.Text = t; 
    }; 
    this.parser.onopentag = function (node) { 
     var node = new xmlNode(node.name, activeNode, node.attributes, dom); 
     if(dom === undefined){ 
      dom = node; 
      activeNode = node; 
     }else{ 
      activeNode.Children.push(node); 
      activeNode = node; 
     } 
    }; 
    this.parser.onclosetag = function (node) { 
     activeNode = activeNode.Parent; 
    }; 

    this.parser.write(xlmText).close(); 
    return dom; 
} 

xmlNode permite un manejo del árbol similar a jquery.

function xmlFilterResult(){ 
    this.length = 0; 
} 

xmlFilterResult.prototype.push = function(element){ 
    this[this.length++] = element; 
} 

xmlFilterResult.prototype.attr = function(atribute){ 
    if(this.length == 0) 
     return ''; 
    return this[0].Attributes[atribute]; 
} 
xmlFilterResult.prototype.text = function(atribute){ 
    if(this.length == 0) 
     return ''; 
    return this[0].Text; 
} 

xmlFilterResult.prototype.children = function(search, result){ 
    if(result == undefined) 
     result = new xmlFilterResult(); 
    if(search == undefined){ 
     for(var i = 0; i < this.length; i++){ 
      this[i].children(search, result); 
     } 
    }else{ 
     this.find(search, true, result); 
    } 
    return result; 
} 
xmlFilterResult.prototype.find = function(search, nonrecursive, result){ 
    if(result == undefined) 
     result = new xmlFilterResult(); 
    if(search.charAt(0) == '.') 
     return this.findAttr('class', search.substring(1), nonrecursive, result); 
    else if(search.charAt(0) == '#') 
     return this.findAttr('id', search.substring(1), nonrecursive, result); 
    else 
     return this.findName(search, nonrecursive, result); 
} 
xmlFilterResult.prototype.findAttr = function(attr, value, nonrecursive, result){ 
    if(result == undefined) 
     result = new xmlFilterResult(); 
    var child; 
    for(var i = 0; i < this.length; i++){ 
     child = this[i]; 
     child.findAttr(attr, value, nonrecursive, result); 
    } 
    return result 
} 
xmlFilterResult.prototype.findName = function(name, nonrecursive, result){ 
    if(result == undefined) 
     result = new xmlFilterResult(); 
    var child; 
    for(var i = 0; i < this.length; i++){ 
     child = this[i]; 
     child.findName(name, nonrecursive, result); 
    } 
    return result 
} 
// xmlFilterResult.prototype.findID = function(id, nonrecursive){ 
    // var child, result = new xmlFilterResult(); 
    // for(var i = 0; i < this.length; i++){ 
     // child = this[i]; 
     // child.findID(id, nonrecursive, result); 
    // } 
    // return result 
// } 




function xmlNode(name, parent, atributes, root){ 
    this.Name = name; 
    this.Children = []; 
    this.Parent = parent; 
    this.Attributes = atributes; 
    this.Document = root; 
    this.Text = ''; 
} 

xmlNode.prototype.attr = function(atribute){ 
    return this.Attributes[atribute]; 
} 
xmlNode.prototype.text = function(atribute){ 
    return this.Text; 
} 

xmlNode.prototype.children = function(search, result){ 
    if(result == undefined) 
     result = new xmlFilterResult(); 
    if(search == undefined){ 
     for(i in this.Children) 
      result.push(this.Children[i]); 
    }else{ 
     return this.find(search, true, result); 
    } 
    return result; 
} 
xmlNode.prototype.find = function(search, nonrecursive, result){ 
    if(search.charAt(0) == '.') 
     return this.findAttr('class', search.substring(1), nonrecursive, result); 
    else if(search.charAt(0) == '#') 
     return this.findAttr('id', search.substring(1), nonrecursive, result); 
    else 
     return this.findName(search, nonrecursive, result); 
} 
xmlNode.prototype.findAttr = function(attr, value, nonrecursive, result){ 
    var child, i; 
    if(result == undefined) 
     result = new xmlFilterResult(); 
    for(i in this.Children){ 
     child = this.Children[i]; 
     if(child.Attributes[attr] == value) 
      result.push(child); 
     if(!nonrecursive) 
      child.findAttr(attr, value, nonrecursive, result); 
    } 
    return result 
} 
xmlNode.prototype.findName = function(name, nonrecursive, result){ 
    var child, i; 
    if(result == undefined) 
     result = new xmlFilterResult(); 
    for(i in this.Children){ 
     child = this.Children[i]; 
     if(child.Name == name){ 
      result.push(child); 
     } 
     if(!nonrecursive) 
      child.findName(name, nonrecursive, result); 
    } 
    return result 
} 

No es nada especial, pero se le ocurre la idea de hacerlo.

Cuestiones relacionadas