Javascript webworker will not load XML file through XMLHttpRequest

I am trying to get a web artist to download an XML file from the same domain on the side of my main page, any help would be greatly appreciated.

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 is executed in the script tag on the main page, I get 3. When working through WebWorker, FireBug gives me

hr.responseXML is null

PostMessage (xhr.responseXML.getElementsByTagName ("value") length.);

In FireBug console, GET Request responded

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

So, the answer is correct, but I can not understand where this is happening. If I change responseXML to responseText, the worker will output

Value Other Value Third Value

It is right! why doesn't the script open it as an XML document?

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 and overrideMimeType are changed, onreadystatechange never works, it doesn’t matter if there is status and readyState there, it will not work. If I completely remove onreadystatechange and run xhr.responseXML, I will get a null error again.

I still get the correct XML as a response in the console, is this a web worker problem, not an httprequest problem? Despair is here :)

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

+6
source share
3 answers

According to the standard, web workers may not have access to any type of DOM manipulation.

DOM APIs (Node objects, Document objects, etc.) are not available to workers in this version of this specification.

responseXML and channel properties are always null from an ajax request, because XML parsing is a DOM API. Regardless of the request and response headers, there will be no way to get requestXML unless you manually parse it.

+3
source

There was the same problem. XML parsing seems to be impossible with webmasters. I used sax.js to parse the XML on a web worker. https://github.com/isaacs/sax-js

This is my main 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 jQuery as tree processing.

 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 } 

Nothing special, but you understand what needs to be done.

0
source

You just need to set the content type header to text/xml on the server side. responseXML is null if the requested document is not XML. In particular, the content type must be one of text/html , text/xml , application/xml or something that ends in +xml . See the specification .

Also see responseXML null and responseXML is always null .

And note: since web workers are essentially asynchronous, you do not need to set the async flag to true when you call open .

-2
source

Source: https://habr.com/ru/post/907269/


All Articles