簡體   English   中英

Javascript webworker不會通過XMLHttpRequest加載XML文件

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

我很想讓一個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為null

的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,則worker輸出

值另一個值第三個值

哪個是對的! 為什么腳本不會將其作為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永遠不會觸發,無論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

根據該標准,Web工作者無法訪問任何類型的DOM操作。

在此規范的此版本中,DOM API(節點對象,文檔對象等)不可用於工作者。

responseXML和channel屬性在ajax請求中始終為null,因為XML的解析是DOM API。 無論請求和響應標頭如何,除非您手動解析它,否則無法獲取requestXML。

有同樣的問題。 顯然,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
}

它沒什么特別的,但你明白了這一點。

您只需要在服務器端將content-type標頭設置為text/xml 如果您請求的文檔不是XML,則responseXML為null。 具體來說,content-type應該是text/htmltext/xmlapplication/xml ,或以+xml結尾的內容。 請參閱規格

另請參閱: responseXML為nullresponseXML始終為null

另請注意:由於Web worker本質上是異步的,因此您無需在open調用中將async標志設置為true。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM