GET from JavaScript, problems parsing XML? Or Maps API errors? - javascript

I'm trying to make an HTTP get from Javascript, calling Google Maps to get transit duration from A to B, and then parsing the resulting XML as follows:
function getTransitTime(match) {
var homeBase = '<Address 1>';
var distURL = 'https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&key=API_KEY_I_GOT&mode=transit&arrival_time=1519977600&origins=' + homeBase + '&destinations=' + match;
parser = new DOMParser();
xmlDoc = parser.parseFromString(httpGet( distURL ), "text/xml");
var finRet = $(xmlDoc).find('duration').text()
return finRet;
}
function httpGet(theUrl)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, true );
xmlHttp.send( null );
return xmlHttp.responseText;
}
I receive both the NoApiKeys and SensorNotRequired errors in the js console. What am I doing wrong?
There are probably even more problems with this:
I'm not sure how to deal with spaces in address 1 (and even worse, "match").
Duration has two sub-fields (one being text), not sure if parsing is correct. Note that my query works correctly in the browser (with the same API key) and the output XML is pasted below:
<DistanceMatrixResponse>
<status>OK</status>
<origin_address>New York, NY, USA</origin_address>
<destination_address>Philadelphia, PA, USA</destination_address>
<row>
<element>
<status>OK</status>
<duration>
<value>5100</value>
<text>1 hour 25 mins</text>
</duration>
<distance>
<value>145447</value>
<text>145 km</text>
</distance>
</element>
</row>
</DistanceMatrixResponse>
Any help? I wandered off trying to make something "simple" work, but ended up in the deep end :|

I've managed to fix this:
First, get permissions to make cross-origin requests to the maps API, by including the following in the extension's manifest.json:
"permissions": ["https://maps.googleapis.com/"]
Next, change:
var finRet = $(xmlDoc).find('duration').text()
to
var finRet = $(xmlDoc).find('duration').find('text').text()
This works because the returned XML has a text tag nested inside the duration tag.
Lastly, the spaces in the URL for the maps call don't really make any difference. Thanks for everyone for reading and contributing. I'm still looking for a cleaner solution if there's one.

Related

How to access local XML in javascript?

I have a html file, where I keep some notes and other info, I frequently update it, so it got quite big. The problem with that was, that if I change something in the layout, it gets really cumbersome, because I have to change it in so many places. So I had the idea, to put all the data into a XML and transform it into HTML with XSLT.
This immediately brought me to the first issue: I'm not able to access the XML.
The first thing I tried was loading it through XMLHttpRequest:
function loadXMLDoc(filename)
{
if (window.ActiveXObject)
{
xhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
else
{
xhttp = new XMLHttpRequest();
}
xhttp.open("GET", filename, false);
xhttp.setRequestHeader('Content-Type', 'application/xml');
try {xhttp.responseType = "msxml-document"} catch(err) {} // Helping IE11
xhttp.send("");
return xhttp.responseXML;
}
But this gets blocked with "Reason: CORS request not HTTP". I know why I get it and I also know that there most likely is no way around that when using XMLHttpRequest. (except tampering with local browser security, which I don't want to do).
My next idea was to put the XML as string directly into the script and just parse it into a XML doc. Something like:
var rawXml = "
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<bar/>
<bar/>
</foo>
";
But this gets me a "Uncaught SyntaxError: "" string literal contains an unescaped line". So apparently javascript doesn't support any form of verbatim strings and I have to escape all the linebreaks with a \n. My problem with that is, that I'm going to loose the pretty formatting. So reading and editing the XML is going to be a pain. That's definitely something I want to avoid.
EDIT:
Thanks to #Taplar for pointing out, that I can use a template literal, which makes the latter approach work.
This solution is not optimal, since I use NotePad++ and I can either use syntax highlighting for HTML or XML, plus XML Tools syntax autocheck gets screwed over by all the HTML code. But so far it is the best solution I have. Should there be any other options left, I'd like to hear them!
(As other people already pointed out to use input type=file, this is no real viable solution for me. I want to open the HTML document and read it. But with the input elements I have to first pick the XML and the pick the XSL. That's kinda cumbersome over which I prefer the xml-as-string solution)
You should set the XMLHttpRequestInstance.responseType to 'document':
function loadXMLDoc(filename, func){
const x = new XMLHttpRequest;
x.open('GET', filename); x.responseType = 'document';
x.onload = d=>{
func(d);
}
x.send();
return x;
}
// here's how you would execute
loadXMLDoc('yourFile.xml', d=>{
const productNodeList = d.getElementsByTagName('product');
});

Internet Explorer 8 parse XML doesn`t work on huge response size

I have a huge page with really lots of data. Sometimes I need to reload this data using Ajax, so ajax request:
if (window.XMLHttpRequest) {
this._request = new XMLHttpRequest();
} else {
this._request = new ActiveXObject("Microsoft.XMLHTTP");
Then, I access this data with request.responseXML. I faced a problem, when size of responsibility more than 800k characters.
IE doesnt generate responseXML, its just empty XMLObject, but in responseText everithing is OK. I`ve tried to parse XML using the following code:
if (request.responseXML) {
var responseXML = request.responseXML;
//TODO: for huge xml responses some versions of IE can't automaticly parse XML
if (O$.isExplorer && responseXML && !responseXML.firstChild) {
var originalResponseText = request.responseText;
if (window.DOMParser) {
var parser = new DOMParser();
responseXML = parser.parseFromString(originalResponseText, 'text/xml');
} else {
responseXML = new ActiveXObject("Microsoft.XMLDOM");
responseXML.async = false;
responseXML.loadXML(originalResponseText);
}
}
But I faced the same problem.
Then, I tried to parse XML using jQuery:
responseXML = jQuery.parseXml(request.responseXML);
But the problem is still the same, everything is fine when the response length small, but for huge response I still get empty XML object with the parse error inside.
errorCode : -2147467259
filepos : 814853
reason : “Unspecified error\r\n”;
I check those position inside response string and everything is correct, just some ordinal symbol. Also I’ve recheck XML lots of time and I am sure that it’s valid. I don’t know what to do at all.
Also I tried to write my own xml parser, but I think that this is problem has more simple solution.
Thanks in Advance.
It would seem that IE notoriously has difficulties parsing XML data, and there may not be that much you can really do about it. A work around is that you can try to parse the XML data with IE, and if it fails, construct a new parser that will construct XML data out of the plaintext (which as you mentioned will work seemingly regardless of size). Take a look at the similar problem and answer here. It boils down to (pseudocode)
function() {
var XMLdata = reponse.XMLdata;
If (XMLdata.error) {
var parser = construct new DOMParser;
XMLdata = parser.XMLparse(response.plaintext);
}
return XMLdata;
}

Calling a website and getting JSON information back

I am not too experienced in javascript on using API's and how to call websites and get information back. I have done this before in Java using HTTP objects and more. I am attempting to make an application where a user can type in a company stock name such as APPL and get back a ton of data like gains, losses, changes, etc. This shouldn't be that hard. I have a html/javascript file with an input textbox for the stock name. This part is easy. But after I tack on the stock name to the end of the URL by concatenation I don't know how to make the call and get the JSON information. There are examples of how to do this in other languages in the web page I am using but not for javascript. I am using this link as a tutorial:
http://digitalpbk.com/stock/google-finance-get-stock-quote-realtime
Here is my javascript code so far: Again this is probably really simple to do. Any help on this would be greatly appreciated and is good to know in the future.
script type="text/javascript">
var submitButton = document.getElementById("submitButton");
submitButton.addEventListener('click', actionPerformed, false);
function actionPerformed(e)
{
var textValue = document.getElementById("stockTextBox").value;
var urlEncoded = "http://finance.google.com/finance/info?client=ig&q=NASDAQ:" + textValue.toString();
for (var i = 0, len = urlEncoded.length; i < len; ++i) {
var object = urlEncoded[i];
confirm(object.toString());
}
}
</script>
I just found the following code for using HTTP GET and tried it out but nothing happens when I click the submit button. Any suggestions on what to do or what's wrong???
function httpGet(theUrl)
{
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false );
xmlHttp.send( null );
return xmlHttp.responseText;
}
Wow, this is turning out to be a lot more work then I had anticipated. Here is the URL string I am using in my code for yahoo finance. I can navigate to it in the browser and it works like a charm. For the life of me I cannot understand why this isn't working.
var urlEncoded = "http://www.finance.yahoo.com/webservice/v1/symbols/" + textValue.toString() + "/quote?format=json";
You could try jQuery, google and download it.
It's a javascript framework that makes things allot simpler .
$.get( "http://yourur.com/file.php?parameter1=value1&parameter2=value2", function( data ) {
//data now contains whatever it loaded from server
console.log("Loaded from server :", data);
}, "json");

Simplest possible method: html break in XML doc

I have a c program which outputs a number of lines to another c program which stuffs them in a PHP page which is loaded with AJAX. The problem is that the output is a number of lines, which is fine to look at, but which, when viewed as HTML, lack line breaks.
The initial thought I had was obviously to put line breaks in with the output. -- That worked fine, especially since I was using responseText to handle the AJAX output. Now I have discovered that along with the raw text, a bit of metadata also needs to be part of the AJAX response. I jumped over to using responseXML, only to find that the tags no longer worked correctly. At this point I could slog through any number of tutorials to figure out how to work some more complicated mechanism, but I really just want a hack. Could I embed the metadata in an html comment and use the DOM to dig it out (I looked and don't see a good method to get to comments using the dom...)? Could I use the xml directly as html somehow? Could I use CDATA in the xml document(this doesn't seem hopeful)? Could I just use newlines until the code reaches the webpage and then have JS insert the br tags?
I don't need any other formatting, just line breaks, and all this needs to do is work, the less complex the better.
How about using a XSLT stylesheet to format your incoming XML. Save the following as an .html file for an example. Sources : http://www.w3schools.com/xsl/xsl_client.asp & http://www.w3schools.com/dom/dom_parser.asp
<html>
<head>
<script>
//YOUR XML FROM AJAX
var XML = "<top><meta><itemone>test meta</itemone></meta><rows><row>line one</row><row>line two</row><row>line three</row></rows></top>";
//A stylesheet to format the lines that come back.
var XSLT = '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="/"><h2>Lines</h2><xsl:for-each select="descendant::row"><xsl:value-of select="self::*"/><br /></xsl:for-each></xsl:template></xsl:stylesheet>'
function loadXMLDoc(xml)
{
var tempXML;
//IE
if (window.ActiveXObject)
{
tempXML=new ActiveXObject("Microsoft.XMLDOM");
tempXML.loadXML(xml);
}
else if(window.DOMParser)
{
parser=new DOMParser();
tempXML=parser.parseFromString(xml,"text/xml");
}
return tempXML;
}
function displayResult()
{
var xmlDoc = loadXMLDoc(XML);
var xsltDoc = loadXMLDoc(XSLT);
// code for IE
if (window.ActiveXObject)
{
var ex=xmlDoc.transformNode(xsltDoc);
document.getElementById("example").innerHTML=ex;
}
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation && document.implementation.createDocument)
{
var xsltProcessor=new XSLTProcessor();
xsltProcessor.importStylesheet(xsltDoc);
var resultDocument = xsltProcessor.transformToFragment(xmlDoc,document);
document.getElementById("example").appendChild(resultDocument);
}
}
</script>
</head>
<body onload="displayResult()">
<div id="example" />
</body>
</html>
Thanks for all the good suggestions, but I eventually decided to just prepend a fixed number of descriptor bytes to each text response and then use the substring command to get either the descriptor bytes or the main text response.
This allows me to keep using the simpler response-text mechanism, and is otherwise uncomplicated.
I would have used custom headers but I realized that that would have required buffering the whole output in yet ANOTHER place since the php script actually only contains a single system() call, and has no idea what the C program behind it is doing.

What is the best method to detect xml in JavaScript

What is the best method to detect xml in JavaScript
e.g. is it possible to detect the mime type of a document - particularly if it is text/xml in JavaScript.
this needs to work in Chrome.
thanks,
Josh
If you are using XMLHttpRequest to get this data, then you can simply check for the Content-Type header using the getResponseHeader method (granted that the server sends the appropriate headers).
var getFile = function(address, responseHandler) {
var req = new XMLHttpRequest();
req.open('get', address, true);
req.onreadystatechange = responseHandler;
req.send(null);
}
var responseHandler = function(resp) {
if ( this.readyState < 4 ) { return; }
console.log(this.getResponseHeader("Content-Type"));
};
getFile("http://zebrakick.com/some/file", responseHandler);
(I seem to be using this code sample a lot...)
You can't determine what the mime-type is with Javascript. I would recommend doing checks on the data returned to see if it is valid XML before you try to parse it. (I'm only assuming what you're trying to do. I can provide a more rigid example if you clarify what your goal is.)
I came across this when looking to determine that a chrome extension script was on an XML page. Maybe this saves someone a few minutes.
In the chrome console and content scripts you can check with:
document.contentType==="application/xml"

Categories

Resources