Microsoft.XMLHTTP documentElement is NULL - javascript

Can someone offer some troubleshooting tips here? My PostXML() return value is NULL for a very small subset of data results. This works for 99.9% of usage. I think the failed data may have special characters perhaps, but comparing to a similar dataset, its identical and passes OK? The oXMLDoc.xml in File.asp contains a valid XML string while debugging, but its null when it gets back to my JS call.
Is there any known issues with what looks like a valid XML element getting trashed in the Microsoft.XMLHTTP object?
function PostXML(sXML)
{
var oHTTPPost = new ActiveXObject("Microsoft.XMLHTTP");
oHTTPPost.Open("POST","File.asp", false);
oHTTPPost.send(sXML);
// documentElement is null???
return oHTTPPost.responseXML.documentElement;
}
File.asp
<%
' oXMLDoc.xml contains valid XML here, but is NULL in the calling JS
Response.ContentType = "text/xml"
Response.Write oXMLDoc.xml
%>

Check the response headers. The content type needs to be application/xml.
XMLHttpRequest is available in current IEs. I suggest using the ActiveX only as a fallback.
You can override the content mimetype on it:
xhr = new XMLHttpRequest();
xhr.overrideMimeType("application/xml");
...
This might by possible on the ActiveX object, too. But I am not sure.
Another possibility is using the DOMParser to convert a received string into an Document instance.

Found the issue.
Using IE Dev/Debugger, I found xEFxBFxBF in one of the string attributes. This product uses MS SQL Server and the query output did not reflect these characters even if copy/pasted into Notepad++. I'm assuming Ent Manager filters out unsupported characters... /=
Thanks for the help people!

Ouch man.
Is it possible to use jQuery instead?
The other thing I know is that if the return xml is a little off (poorly formatted xml, case sensitive, non-legal characters) the javascript will trash the return value.
With jQuery you have better debugging options to see the error.

Related

How to count children of xml element?

I know this has been asked before, but I'm kinda lost here.
I've got an element from which I log the typeof:
typeof msg['PID']['PID.13'] // outputs "xml"
So following this answer I logged the children.length, of which I expect it to be a number:
typeof msg['PID']['PID.13'].children.length // also outputs "xml"
But the typeof the children.length is also xml. How can this be?
It's Javascript hidden in a system (Mirth) in which logging is a problem (at least I still haven't found out how it works) so I'm having a hard time debugging this.
Does anybody know how I can get the children count of the element? All tips are welcome!
[EDIT]
As suggested I also tried the output of msg['PID']['PID.13'].children.length, but that seems to be empty.
First thing that seems pretty strange to me is: typeof msg['PID']['PID.13'] // 'xml'. So, in case you get some xml from the server, you can parse it like so:
var parser = new DOMParser(),
doc = parser.parser.parseFromString(xml, 'text/xml'); //xml is a xml string
typeof doc // 'object'
Than, to count the occurrences of some elements/children, you can use xpath:
var count = doc.evaluate('count(//someelement)', doc.documentElement, null, XPathResult.NUMBER_TYPE, null).numberValue;
You can even run:
doc.querySelectorAll('someelement').length
and those methods from the comments will work, too:
doc.documentElement.children.length
So I guess the xml object you have in that object is not a real XMLDocument, that is why I guess those properties like msg['PID']['PID.13'].children.length »seam to be empty«.
UPDATE
As pointed out in the answer of #Nick Rupley you might be dealing with an Instance of E4X, and as documented here, in the Archive of obsolete content, it is obsolete in firefox and does not appear at all on caniuse.com. So if your code is running in a Browser, you need to change it to one of the variants mentioned above. Otherwise you can find documentation about the usage on the first linked resource on mdn.
What you have there is an E4X XML (or XMLList) object. So do this instead:
msg['PID']['PID.13'].children().length()
So, msg['PID']['PID.13'] is xml. Can you post it as text here?
If that xml was something like <children><length><value>5</value></length></children> then, perhaps, msg['PID']['PID.13'].children could have been interpreted by js as if it was msg['PID']['PID.13']['children'] which is identical js expression. Similarly, dependending on what type of object that is, it could return empty xml node for all invalid nodes, that is:
typeof msg['PID']['PID.13'].children.a.b.c.d.length
would also return xml.

Is ?& allowed in URL

I was reviewing some code and I saw something like this:
if (result.indexOf('?') === -1) {
result += '?';
}
result += '&' + SOMETHING;
Clearly this can result in an URL like this http://example.com?&a=b
The author of the code sees nothing unusual in the code but ?& bothers me. I could not find any restrictions in the RFC for URI to prove him wrong (or maybe I missed it).
Clearly in the network tab of Chrome dev tools it appears as an empty pair:
Should URL like this bother me or am i just paranoid?
This case will be interpreted as an empty value by most servers, so yes, it is indeed valid. What's going to happen is that the server checks between ? and every & and then separates the values at = accordingly.
So when there is nothing between a ? and a & (or two &'s), the values will both be empty. Missing ='s will affect whether the value is "" or null, but it will not make the query invalid.
Watch out with this, because some parsers might not find this to be valid, so you may get problems when using custom parsers (in JavaScript for example).
I wrote up a blog post about some of these edge cases years ago.
tl;dr: yes, ?&example is valid
What's important about it is that you're defining a key of "" with a value of null.
You can pretty much guarantee that almost no libraries support those empty string keys, so don't rely on them working, but as far as having a URL along the lines of ?&foo=bar, you should be fine when accessing the foo key.

quick Jquery .load chat not working

I have the following jquery:
var msg = $("#newmessage").val();
var user = $("#userchat").val();
var filename = "/inc/chat.php?msg="+msg+"&user="+user;
alert(filename);
$("#chatData").load(filename);
when 'msg' does not have a space in it, the #chatData loads fine and posts the variable.
When it does have a space in it, I just get a blank div. With no information in it whatsoever.
if I load up the php file that inserts the data into the DB, and manually type the same GET data, it works fine.
Whats going on?
Try using
encodeURIComponent(msg)
Also consider:
$("#chatData").load('/inc/chat.php',
{ 'msg' : $("#newmessage").val(), 'user' : $("#userchat").val() }
);
URI encoding is done, if needed, by jQuery.
You don't have to worry about URI encoding as the POST method is used since data is provided as an object (source).
In this case POST may be better than GET anyways.
If you were using $_GET in your php file you will need to use either $_REQUEST or $_POST.
you have to encode your message before sending using encodeURIComponent() and decode on server-site using urldecode().
doing this will escape/encode special characters that aren't allowed in an url or that will break your query-string otherwise (like a & in your message that would otherwise start a new argument).
You can use either escape, encodeURI or encodeURIComponent, but escape is the only method supported by every browser, although most modern browsers support the latter.
Reference
Take a look at this document, which does a good job of explaining all three.
The space could be causing an issue - try javascript's encodeURIComponent():
var msg = encodeURIComponent($("#newmessage").val());
var user = encodeURIComponent($("#userchat").val());

Extracting values with Javascript

I have a variable called "result",
var result;
that result value is equal to following value, please presume that is just a string :)
---------result value -----------
for (;;);{
"send":1,
"payload":{
"config":{
"website":"",
"title":"welcome to site",
"website-module":1313508674538,
"manufatureid":"id.249530475080015",
"tableid":"id.272772962740259",
"adminid":100002741928612,
"offline":null,
"adminemail":"admin#website.com",
"adminame":"George",
"tags":"web:design:template",
"source":"source:design:web",
"sitelog":[],
"errorlog":0,
"RespondActionlog":0,
"map":null
},
"imgupload":""
},
"criticalerror":[0],
"report":true
}
---------result value------------
From that value, I would like to extract tableid which is "id.272772962740259" with classic Javascript.
How can I extract the code, please let me know how can i do with simple javascript, please don't use Jquery, all I just need is simple javascript.
You can simply evaluate the value of the variable to obtain the values. However, please note that your current value is not valid JSON; that for(;;); at the beginning of the value invalidates the format. Remove that, and you can do this:
var object = eval('(' + resultMinusThatForLoop + ')');
alert(object.payload.config.tableid);
If that data is a string the parse it with a JSON parse. The following should get the value you want
JSON.parse(result).payload.config.tableid; // "id.272772962740259"
Edit: though, as Tejs says, the for(;;) invalidates the string and stops it from being parsed. If you can remove that, do.
You need to remove the empty for loop, then parse the string. DO NOT use eval; most modern browsers provide built-in JSON-parsing facilities, but you can use json2.js if yours does not. Assuming that you assign the results of parsing the JSON to result, you should be able to get that value using result.payload.config.tableid.
You should probably read a good JS reference. JavaScript: The Good Parts or Eloquent JavaScript would be a good choice.
If result is a javascript object and not a string, you can just use 'result.payload.config.tableid'.
If it is not, how do you get the AJAX result? Are you using XmlHttpRequest directly? Most libraries will give you a javascript object, you might be missing a flag or not sending the response back with the right content type.
If it is a string and you want to parse it manually, you should use a JSON parser. Newer browsers have one built in as window.JSON, but there is open source code for parsing it as well.
var obj = JSON.parse(result);
alert('tableid is ' + obj.payload.config.tableid);

Regex to match contents of HTML body

EDIT: OOPS, sorry I wasn't clear. I have a string that I get from AJAX that is an xhtml document, I need to get the body tag of it, unless I can generate a dom tree from the string?
I need to get everything from a body tag in a string, including markup, with a javascript regex.
I know that this is a duplicate, but the regexes I found in other questions were for different flavours of regex, and gave me errors.
Thank in advance.
document.getElementsByTagName('body')[0].innerHTML will return a string of everything in the body tag. It's not a regex, but I'm not sure why you need one...?
POST QUESTION EDIT:
Your XHR object that you performed your AJAX with has responseText and responseXML properties. As long as the response is valid xml, which is probably should be, you can get any tag you want using getElementsByTagName on the xml object that I mentioned. But if you just want the inner parts of the body, I would do it this way:
var inner = myXHR.responseText.split(/(<body>|</body>)/ig)[2]);
Regex isn't the ideal tool for parsing the DOM as you will see mentioned throughout this site and others. The most ideal way, as suggested by George IV is to use the JavaScript tools that are more suited to this and that is getElementsByTagName and grab the innerHTML:
var bodyText = document.getElementsByTagName("body")[0].innerHTML;
Edit1: I've not checked it out yet, but Rudisimo suggested a tool that shows a lot of promise - the XRegExp Library which is an open sources and extensible library out of MIT. This could potentially be a viable option - I still think the DOM is the better way, but this looks far superior to the standard JavaScript implementation of regex.
Edit2: I recant my previous statements about the Regex engine [for reasons of accuracy] due to the example provided by Gumbo - however absurd the expression might be. I do, however, stand by my opinion that using regex in this instance is an inherently bad way to go and you should reference the DOM using the aforementioned example.
In general regular expressions are not suitable for parsing. But if you really want to use a regular expression, try this:
/^\s*(?:<(?:!(?:(?:--(?:[^-]+|-[^-])*--)+|\[CDATA\[(?:[^\]]+|](?:[^\]]|][^>]))*\]\]|[^<>]+)|(?!body[\s>])[a-z]+(?:\s*(?:[^<>"']+|"[^"]*"|'[^']*'))*|\/[a-z]+)\s*>|[^<]+)*\s*<body(?:\s*(?:[^<>"']+|"[^"]*"|'[^']*'))*\s*>([\s\S]+)<\/body\s*>/i
As you see, there is no easy way to do that. And I wouldn’t even claim that this is a correct regular expression. But it should take comment tags (<!-- … -->), CDATA tags (<![CDATA[ … ]]>) and normal HTML tags into account.
Good luck while trying to read it.
Everybody seems dead set on using regular expressions so I figured I'd go the other way and answer the second query you had.
It is theoretically possible to parse the result of your AJAX as an xmlDocument.
There are a few steps you'll likely want to take if you want this to work.
Use a library. I recommend jQuery
If you're using a library you must make sure that the mimetype of the response is an xml mimetype!
Make sure you test thoroughly in all your target browsers. You will get tripped up.
That being said, I created a quick example on jsbin.
It works in both IE and Firefox, unfortunately in order to get it to work I had to roll my own XMLHttpRequest object.
View the example source code here
(Seriously though, this code is ugly. It's worth using a library and setting the mime type properly...)
function getXHR() {
var xmlhttp;
//Build the request
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else if (window.ActiveXObject) {
// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
} else {
alert("Your browser does not support XMLHTTP!");
}
//Override the mime type for firefox so that it returns the
//result as an XMLDocument.
if( xmlhttp.overrideMimeType ) {
xmlhttp.overrideMimeType('application/xhtml+xml; charset=x-user-defined');
}
return xmlhttp;
}
function runVanillaAjax(url,functor)
{
var xmlhttp = getXHR();
xmlhttp.onreadystatechange=function() { functor(xmlhttp); };
xmlhttp.open("GET",url,true);
xmlhttp.send(null);
}
function vanillaAjaxDone( response ) {
if(response.readyState==4) {
//Get the xml document element for IE or firefox
var xml;
if ($.browser.msie) {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(response.responseText);
} else {
xml = response.responseXML.documentElement;
}
var textarea = document.getElementById('textarea');
var bodyTag = xml.getElementsByTagName('body')[0];
if( $.browser.msie ) {
textarea.value = bodyTag.text;
} else {
textarea.value = bodyTag.textContent;
}
}
}
function vanillaAjax() {
runVanillaAjax('http://jsbin.com/ulevu',vanillaAjaxDone);
}
There is an alternative fix to the dot matches newline limitation of the RegExp library in JavaScript. XRegExp is a powerful and open source library with an almost limitless license "MIT License" (for commercial projects), which is very compact (2.7KB gzipped) and powerful.
If you go to the New Flags section, you can see how there's a flag (s), in which dot matches all characters; including newlines.

Categories