简体   繁体   English

Javascript webworker不会通过XMLHttpRequest加载XML文件

[英]Javascript webworker won't load XML file via XMLHttpRequest

I'm am strugling to get a webworker to load an XML file from the same domain on the side of my main page, any help would be greatly appreciated. 我很想让一个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);
 }
}

When this runs in a script tag on the main page, i get a 3. When running thru the WebWorker, FireBug gives me 当它在主页上的脚本标签中运行时,我得到3.当通过WebWorker运行时,FireBug给了我

hr.responseXML is null hr.responseXML为null

postMessage(xhr.responseXML.getElementsByTagName("value").length); 的postMessage(xhr.responseXML.getElementsByTagName( “值”)的长度。);

In the FireBug console, GET Request responded with 在FireBug控制台中,GET请求响应

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

So the response is correct but i cannot figure out where it's going wrong. 所以答案是正确的,但我无法弄清楚它出错的地方。 If i change responseXML to responseText the worker outputs 如果我将responseXML更改为responseText,则worker输出

A value Another Value A third Value 值另一个值第三个值

Which is correct! 哪个是对的! why won't the script open it as an XML document? 为什么脚本不会将其作为XML文档打开?

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

When setRequestHeader & overrideMimeType is changed, the onreadystatechange never fires, doesn't matter if status and readyState are there or not, it won't run. 当setRequestHeader和overrideMimeType被更改时,onreadystatechange永远不会触发,无论status和readyState是否存在,它都不会运行。 If i remove the onreadystatechange completely and just run xhr.responseXML, i get the null error again. 如果我完全删除onreadystatechange并运行xhr.responseXML,我再次得到null错误。

I still get the correct XML in as response in the console, is this a webworker issue instead of a httprequest problem? 我仍然在控制台中获得正确的XML作为响应,这是一个webworker问题而不是httprequest问题? Getting desperate here :) 在这里绝望:)

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

According to the standard, Web workers can have not have access to any type of DOM manipulation. 根据该标准,Web工作者无法访问任何类型的DOM操作。

The DOM APIs (Node objects, Document objects, etc) are not available to workers in this version of this specification. 在此规范的此版本中,DOM API(节点对象,文档对象等)不可用于工作者。

responseXML and channel properties are always null from an ajax request as the parsing of the XML is a DOM API. responseXML和channel属性在ajax请求中始终为null,因为XML的解析是DOM API。 No matter the request and response headers there will be no way of getting requestXML unless you manually parse it. 无论请求和响应标头如何,除非您手动解析它,否则无法获取requestXML。

Had the same Problem. 有同样的问题。 Apparently XML parsing is not possible in webworkers. 显然,Web工作者无法进行XML解析。 I used sax.js to parse a XML on web worker. 我使用sax.js来解析web worker上的XML。 https://github.com/isaacs/sax-js https://github.com/isaacs/sax-js

this is basicly my parser. 这基本上是我的解析器。

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 enables a jquery like handling of the tree. 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
}

Its nothing special but you get the idea of that to do. 它没什么特别的,但你明白了这一点。

You just need to set the content-type header to text/xml on the server side. 您只需要在服务器端将content-type标头设置为text/xml responseXML is null if the document that you're requesting isn't XML. 如果您请求的文档不是XML,则responseXML为null。 Specifically, the content-type should be one of text/html , text/xml , application/xml , or something that ends in +xml . 具体来说,content-type应该是text/htmltext/xmlapplication/xml ,或以+xml结尾的内容。 See the spec . 请参阅规格

Also, see: responseXML is null and responseXML always null . 另请参阅: responseXML为nullresponseXML始终为null

And a side note: since web workers are inherently asynchronous, you don't need to set the async flag to true in your open call. 另请注意:由于Web worker本质上是异步的,因此您无需在open调用中将async标志设置为true。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM