Javascript веб-работник не будет загружать XML-файл через XMLHttpRequest - PullRequest
6 голосов
/ 31 января 2012

Я изо всех сил пытаюсь заставить веб-работника загрузить 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?

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 в качестве ответа в консоли, это проблема веб-работника, а не проблема httprequest? Отчаянно здесь:)

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

Ответы [ 3 ]

3 голосов
/ 09 мая 2012

Согласно стандарту, веб-работники могут не иметь доступа ни к какому типу манипуляций с DOM.

API DOM (объекты Node, объекты Document и т. Д.) Недоступны работникам в этой версии данной спецификации.

responseXML и свойства канала всегда равны нулю в запросе ajax, так как синтаксический анализ XML - это DOM API. Независимо от заголовка запроса и ответа, невозможно получить requestXML, если вы не проанализируете его вручную.

1 голос
/ 02 мая 2014

Была такая же проблема.По-видимому, синтаксический анализ XML невозможен для веб-работников.Я использовал sax.js для разбора 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
}

Ничего особенного, но вы получаетеИдея этого делать.

0 голосов
/ 31 января 2012

Вам просто нужно установить заголовок типа контента на text/xml на стороне сервера.responseXML равно нулю, если запрашиваемый вами документ не является XML.В частности, тип содержимого должен иметь тип text/html, text/xml, application/xml или что-то, заканчивающееся на +xml.См. спецификацию .

Также см .: responseXML имеет значение null и responseXML всегда имеет значение .

И примечание: поскольку веб-работники изначально асинхронны, вам не нужно устанавливать флаг асинхронности в true при вызове open.

...