I have file main.log something like :
10-01-1970 01:42:52 Bus_Power device 9 up
10-01-1970 01:42:52 External_Power device 9 up
10-01-1970 01:42:57 Bus_Power device 1 down
10-01-1970 01:42:57 Bus_Power device 2 down
Every row is one data. How to parse this in array of rows using Dojo or plain JavaScript ?
for example :
['10-01-1970 01:42:52 Bus_Power device 9 up','10-01-1970 01:42:52 External_Power device 9 up']
var xhr = new XMLHttpRequest();
xhr.open('GET', 'main.log', false);
xhr.send(null);
var log = xhr.responseText.split('\n');
// `log` is the array of logs you want
Note: Done synchronously, for simplicity, as no details were given about application of this functionality.
If you have the file into a string (say 'text'), then you can do:
var lines = text.split("\n");
Check if your file on the server terminates lines with just one line-feed (UNIX-style) or a CR-LF pair (Windows-style).
How do you get the file into a string in the first place? You can use dojo.xhrGet(...). Look it up in the Dojo docs.
Say you're reading a text/log file, the following codes are modified from another post of stackflow.com,
var contentType = "application/x-www-form-urlencoded; charset=utf-8";
var request = new XMLHttpRequest();
request.open("GET", 'test.log', false);
request.setRequestHeader('Content-type', contentType);
if (request.overrideMimeType) request.overrideMimeType(contentType);
// exception handling
try { request.send(null); } catch (e) { return null; }
if (request.status == 500 || request.status == 404 || request.status == 2 || (request.status == 0 && request.responseText == '')) return null;
lines = request.responseText.split('\n')
for( var i in lines ) {
console.log(lines[i]);
}
Problems may caused by encoding/decoding issue, so we may need exception handing as well. For more information about XMLHttpRequest, pls visit here.
Related
I'm running a Heroku server and I'm trying to change the innerHTML on my website to display certain statistics gathered from an endpoint on the server:
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.send();
xhr.onreadystatechange = processRequest;
var element = document.getElementById('change');
element.innerHTML = xhr.valueinJSON;
function processRequest(e) {
if (xhr.readyState == 4 && xhr.status == 200) {
var response = JSON.parse(xhr.responseText);
alert(response.ip);
}
}
My script tag contains the above and although the endpoint works properly in Postman, the JSON is always null. Any suggestions?
I'm not sure if valueinJSON is from an API I'm not familiar with, but I can't find a reference to it. Either way, you need to change your innerHTML in the async function like this:
if (xhr.readyState == 4 && xhr.status == 200) {
var response = JSON.parse(xhr.responseText);
var element = document.getElementById('change');
element.innerHTML = response
}
You are trying to set the innerHTML before the browser has a chance to download it.
This assumes there is not a CORS issue. You should check your browser's console to make sure there are not errors.
In my question from yesterday, I asked how to retrieve the full HTML content as text. Seems like XHR is the way. Now, however, I have a different problem.
I use this code to retrieve the content of the document as a string:
var req = new XMLHttpRequest();
req.open("GET", document.location.href);
req.onreadystatechange = function () {
if (req.readyState === 4 && (req.status === 200 || req.status == 0)) {
console.log(req.responseText);
}
};
req.send(null);
However, there is a slight delay that I'd like to avoid. I'm testing on localhost and Chrome DevTools says there's several milliseconds of "Stalled" time. In the "Size" column, it says "(from disc cache)", so I know I'm requesting something that the client already has.
Questions
Since the request is about something that already exists, can I somehow make the response instantaneous?
Can I access the original request (the one that is fired after typing the website URL) and access its response text?
My goal is to get the document as a string as soon as possible and without waiting for the DOM to load.
You could implement a cache:
function retrieve(url,callback){
if(localStorage.getItem(url)){
return callback(localStorage.getItem(url));
}
var req = new XMLHttpRequest();
req.open("GET", document.location.href);
req.onreadystatechange = function () {
if (req.readyState === 4 && (req.status === 200 || req.status == 0)) {
localStorage.setItem(url,req.responseText);
callback(req.responseText);
}
};
req.send(null);
}
retrieve("http://test.com",console.log);//takes its time
setTimeout(retrieve,1000,"http://test.com",console.log);//should be very fast...
Also if you want to get the current response, why dont you simply access the document bject?
I use the code below to get a web page(html)
var htmlString=null;
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.yahoo.com");//can change to any web address
xhr.onreadystatechange = function() {
htmlString=htmlString+xhr.responseText;
if(xhr.statusText=="200 OK\r" ){
log (global.htmlString.length);
}
}
but it always get one part of the page, rather than whole html code
Is there any parameter to set the length of the return html code?
Your comment welcome
There will be multiple readystatechange events. The request will only be completely done when xhr.readyState === XMLHttpRequest.DONE === 4.
Also, htmlString = null; ...; htmlString=htmlString+xhr.responseText; is bogus in many ways. First time around it will do htmlString = null + "text" === "nulltext. Afterwards it will add .responseText (as retrieved so far) again and again, while going through the states.
Also, on a related note, you should check xhr.status == 200, not xhr.statusText == randomString. Web servers aren't necessarily sending "OK" in case of 200.
Read the XMLHttpRequest documentation.
Something like this should work better:
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.yahoo.com");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 /* DONE */) {
console.log(xhr.responseText.length);
// Do something with it...
}
}
xhr.send();
Let's say I have a text file on my web server under /today/changelog-en.txt which stores information about updates to my website. Each section starts with a version number, then a list of the changes.
Because of this, the first line of the file always contains the latest version number, which I'd like to read out using plain JavaScript (no jQuery). Is this possible, and if yes, how?
This should be simple enough using XHR. Something like this would work fine for you:
var XHR = new XMLHttpRequest();
XHR.open("GET", "/today/changelog-en.txt", true);
XHR.send();
XHR.onload = function (){
console.log( XHR.responseText.slice(0, XHR.responseText.indexOf("\n")) );
};
So seeing as the txt file is externally available ie: corresponds to a URL, we can do an XHR/AJAX request to get the data. Note without jQuery, so we'll be writing slightly more verbose vanilla JavaScript.
var xmlHttp;
function GetData( url, callback ) {
xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = callback;
xmlHttp.open( "GET", url, true );
xmlHttp.send( null );
}
GetData( "/today/changelog-en.txt" , function() {
if ( xmlHttp.readyState == 4 && xmlHttp.status == 200 {
var result = xmlHttp.responseText;
var allLines = result.split("\n");
// do what you want with the result
// ie: split lines and show the first line
var lineOne = allLines[0];
} else {
// handle the error
}
});
I'm doing an AJAX fetch of a binary file the I am parsing in javascript. (Quake 2 BSPs, if anyone cares.) The code to fetch and parse the initial file is working fine, and looks roughly like this:
function loadFile(url) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
var parsed = parseFile(request.responseText);
}
};
request.open('GET', url, true);
request.overrideMimeType('text/plain; charset=x-user-defined');
request.setRequestHeader('Content-Type', 'text/plain');
request.send(null);
}
As I said, that works fine, and everything loads and parses correctly. However, the file also describes several secondary files (textures) that need to be retrieved as well, and so I've added an inner loop that should load and parse all of those files, like so:
function loadFile(url) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
var parsed = parseFile(request.responseText);
for(var i = 0; i < parsed.files.length; ++i) {
loadSecondaryFile(parsed.files[i].url); // Request code here is identical to this function
}
}
};
request.open('GET', url, true);
request.overrideMimeType('text/plain; charset=x-user-defined');
request.setRequestHeader('Content-Type', 'text/plain');
request.send(null);
}
function loadSecondaryFile(url) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
var parsed = parseSecondaryFile(request.responseText);
}
};
request.open('GET', url, true);
request.overrideMimeType('text/plain; charset=x-user-defined');
request.setRequestHeader('Content-Type', 'text/plain');
request.send(null);
}
But every request made from within that loop immediately fails with the message (in Chrome, Dev Channel): NETWORK_ERR: XMLHttpRequest Exception 101 This strikes me as strange, since if I call loadSecondaryFile outside of loadFile it works perfectly.
My initial impression was that initiating an one ajax call in the onreadystatechage of another may be bad juju, but wrapping the secondary ajax calls in a setTimer doesn't make any difference.
Any ideas?
And... SUCCESS! So I feel really stupid, and I realize now that there's no way anyone else could have given me a solution with the information I presented. Terribly sorry!
It has nothing to do with AJAX and everything to do with how I was getting my URLs. Recall that I mentioned I was loading binary data from a Quake2 bsp, in this case, texture paths. Textures in the bsp format are stored as fixed length 32 bit strings with null padding. I was reading them using substr like so:
var path = fileBuffer.substr(fileOffset, 32);
Which I thought was giving me a string like "e2u3/clip", but in reality was giving me "e2u3/clip\0\0\0\0..." Of course, when printed this would look correct (since console.log represents the null char as nothing.) but the browser recognized it immediately as a bad URL and tossed it out.
Changing my read code to:
var path = fileBuffer.substr(fileOffset, 32).replace(/\0+$/,'');
Gives me valid strings and fixes all of my apparent AJAX problems! sigh
Thanks for all the suggestions! It helped put me on the right track.