我很想让一个webworker从我主页面的同一个域加载一个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运行时,FireBug给了我
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文档打开?
更新
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&amp; overrideMimeType被更改,onreadystatechange永远不会触发,无论status和readyState是否存在都无关紧要,它将不会运行。如果我完全删除onreadystatechange并运行xhr.responseXML,我再次得到null错误。
我仍然在控制台中获得正确的XML作为响应,这是一个webworker问题而不是httprequest问题吗?在这里绝望:)
index.html http://www.axlonline.se/worker/index.html
worker.js http://www.axlonline.se/worker/worker.js
答案 0 :(得分:3)
根据标准,Web工作者无法访问任何类型的DOM操作。
此规范的此版本中的工作人员无法使用DOM API(节点对象,文档对象等)。
responseXML和channel属性在ajax请求中始终为null,因为XML的解析是DOM API。无论请求和响应标头如何,除非您手动解析它,否则无法获取requestXML。
答案 1 :(得分:1)
有同样的问题。显然,Web工作者无法进行XML解析。 我使用sax.js来解析web worker上的XML。 https://github.com/isaacs/sax-js
这基本上是我的解析器。
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
}
它没什么特别的,但你明白了这一点。
答案 2 :(得分:-2)
您只需在服务器端将内容类型标头设置为text/xml
即可。
如果您请求的文档不是XML,则responseXML
为null。具体而言,内容类型应为text/html
,text/xml
,application/xml
之一,或以+xml
结尾的内容。请参阅the spec。
另请参阅:responseXML is null和responseXML always null。
请注意:由于Web worker本身是异步的,因此您无需在open
调用中将async标志设置为true。