2012-01-30 61 views
6

我正在努力让webworker从我的主页上的同一个域加载XML文件,任何帮助将不胜感激。Javascript webworker将不会通过XMLHttpRequest加载XML文件

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); 
} 
} 

当这个运行在主网页上的脚本标签,我得到一个3 通时的WebWorker运行,萤火给我

hr.responseXML为空

的postMessage (xhr.responseXML.getElementsByTagName( “值”)的长度);

在Firebug控制台,GET请求回应

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

所以反应是正确的,但我无法弄清楚它是怎么回事错了。 如果我改变的responseXML来的responseText工人产出

值的另一个值的第三值

这是正确的!为什么脚本不能将其作为XML文档打开?

UPDATE

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); 
} 
} 

当setRequestHeader & overrideMimeType改变时,onreadystatechange的永远不会触发,不要紧,如果状态和readyState的是有或没有,它不会运行。如果我完全删除onreadystatechange并运行xhr.responseXML,则会再次出现空错误。

我仍然在控制台中得到正确的XML作为响应,这是一个webworker问题而不是httprequest问题?抵达该处绝望:)

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

回答

-2

你只需要在内容类型标题设置为text/xml在服务器端。如果您请求的文档不是XML,则为 responseXML为空。具体而言,内容类型应该是text/html,text/xml,application/xml之一,或以+xml结尾的内容。见the spec

另外,参见:responseXML is nullresponseXML always null

另外还有一个提示:由于web worker本质上是异步的,因此您不需要在调用open时将async标志设置为true。

+0

我添加requestheader并尝试覆盖MIME类型后仍然不起作用,responseXML仍为空。 这似乎是webworker的问题,因为脚本在主文档中工作得很好。 – axlOnline 2012-01-31 12:01:20

+0

我有同样的问题; mime类型在响应脚本中设置为text/xml,xmlhttprequest readystate为4,responseType为空,responseXML为null。令人沮丧。 我一直在使用的一种解决方法是将XML转换为PHP中的JSON,然后返回该结果,并使用JSON.parse,这非常有用。 – 2012-04-19 12:21:56

3

根据标准,Web工作人员可能无法访问任何类型的DOM操作。

此规范的此版本中的DOM API(节点对象,Document对象等)不适用于工作人员。

responseXML和通道属性始终为空,因为解析XML是DOM API。无论请求和响应头文件,除非您手动解析它,否则无法获取requestXML。

+1

JSON.parse另一方面是可用的。这将允许您将@Xon_Fournier所说的服务器端的XML更改为JSON – georgephillips 2012-05-09 02:36:58

0

有同样的问题。显然,网络工作者不可能使用XML解析。 我使用sax.js来解析web worker上的XML。 https://github.com/isaacs/sax-js

这是basicly我的解析器。

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使像处理树的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 
} 

它没有什么特别的,但你会明白这一点。