dynamically loading JSON file from javascript - javascript

On my RPi I have an application (developed in C++) running in the background that does some complex mathematics based on some sensor input and produces some result every second. I want to display this data on a website. So I had the idea to have the application produce a JSON formatted file and read that interactively from a javascript script.
The app now produces a file ModelState.json in my html directory that looks like
{ "x" : -0.886289 , "y" : -0.434931 }
Based on this answer, I wrote the following html/js
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p id="ModelState"></p>
</body>
<script type="text/javascript">
window.onload = function () {
setInterval(showModelState, 1000);
function showModelState() {
readJsonFile("ModelState.json", function(ModelStateJson){
var ModelStateObj = JSON.parse(ModelStateJson);
if (ModelStateObj.x && ModelStateObj.y) {
document.getElementById("ModelState").innerHTML =
"x: " + ModelStateObj.x + ", " +
"y: " + ModelStateObj.y;
}
});
}
function readJsonFile(file, callback) {
let rawFile = new XMLHttpRequest();
rawFile.overrideMimeType("application/json");
rawFile.open("GET", file, true);
rawFile.onreadystatechange = function() {
if (rawFile.readyState === 4 && rawFile.status === 200) {
callback(rawFile.responseText);
}
}
rawFile.send(null);
}
}
</script>
</html>
However, what I observe is that the file seems to be loaded once. The data on the webpage doesn't change, while the data in the file does change.
I don't know why. Is it that the XMLHttpRequest keeps the file open, such that onreadystatechange is not triggered and the callback function is not called again? I would expect the send response to finish the request, thus close the file.

As cristobal states in the comments, the problem is caused by the browser caching the read file.
One solution is to confuse the browser with a dynamic url, e.g. by changing
readJsonFile("ModelState.json", function(...
to
readJsonFile("ModelState.json?time=${Date.now()}", function(...
An alternative solution (based on this) is that the browser doesn't cache POST http request methods. Thus you can change
rawFile.open("GET", file, true);
to
rawFile.open("POST", file, true);
A third solution (found here) is to add a pragma after the line rawFile.open("GET"...
rawFile.setRequestHeader("Pragma", "no-cache");
More elaborate request headers for cache control can be found here

Related

Best way to get file last modified attribute

What would be the best way to get the "last modified" attribute from a file NOT on the web server. My purpose is to display the time stamps of specific network files in a web page. All the JavaScript references I have found are for the current file, or from the web server. I have found references for browsing to, drag-and-drop, etc. But I would like to read the file attribute from the original location. Is this even possible??
EDIT:
So now that I have a batch file to create the text file on the web server, how do I get that data into an array so I can display it properly? The data is correct, but it is one long string.
This is my code:
<html>
<head>
<script type="text/javascript">
function getStatus() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("backupStatus").innerHTML = xhttp.responseText;
}
};
xhttp.open("GET", "file.txt", true);
xhttp.send();
}
</script>
</head>
<body>
<button type="button" onclick="getStatus()">Get QNAP Backup Status</button>
<ul id="backupStatus">
</ul>
</body>
</html>
This is my output:
#ECHO 4/13/2016 #FREEMAN1 4/13/2016 #FREEMAN02 4/13/2016 #FREEMAN03 4/7/2016 #FREEMAN4 4/7/2016 #FREEMAN5 4/7/2016 #HR10 4/13/2016 #ACCOUNTING20 4/12/2016 #IT01 4/13/2016 #PROD20 4/12/2016 #UPS10 4/13/2016
javascript can't go out and read files on a user's computer. You'd need to read this information on a server and load it in to the page, or via an ajax call.

Javascript : Different behavior when run on machine and local server

Because my title is too short, I will explain more clearer. I have create a code in JavaScript . And I have two options to run :
1) Run on machine : simple click into html file.
2) Run on local server : mean I start Apache, and start this html file in localhost.
( http://localhost:85/Javascript/index.html for example)
When I choose solution 1, no thing happen. And when I choose solution 2, happen as I wish. But I don't know why.
Here is my code. Purpose : take a json file and process it.
<script>
window.onload = function(){
var url = "http://localhost:85/javascript/json1.json"; // problem here
var request = new XMLHttpRequest();
request.open("GET", url);
request.onload = function(){
if (request.status == 200){
update(request.responseText);
}
}
request.send(null);
};
function update(responseText){ // some code here }
</script>
You cannot use AJAX to read content from a different domain.
Javascript running from file://whatever cannot read localhost:85.
Did you replace this line with the server's original path?
var url = "http://localhost:85/javascript/json1.json";
With
var url = "http://10.0.0.X:85/javascript/json1.json"; // Did you change the right path?
And make sure, the page is not called with the file:// protocol!

Web Service call using javascript returns nothing in responseXML

I see this same question asked a few times in this forum and I have applied the suggested answers but I continue to have a problem. That problem being that when I call a web service using javascript the response comes back empty, while I successfully receive data (a valid XML document) calling the web service in any browser.
Here is my javascript code in an HTML page:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/xml">
<title> MY HTML page </title>
<script language="JavaScript">
function doWebSvce()
{
if (window.XMLHttpRequest) {
xhttp=new XMLHttpRequest();
}
else if (window.ActiveXObject) {
XObject("Microsoft.XMLHTTP");
xhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
var url = "http://www.webservicex.net/stockquote.asmx/GetQuote?symbol=IBM";
xhttp.open("GET", url, true);
xhttp.onreadystatechange = getData;
xhttp.send("");
}//end doWebSvce
function getData()
{
if (xhttp.readyState == 4)
{
alert("2nd in getData... \r\xhttp.readyState = "+ xhttp.readyState +" \r\n
xhttp.status= "+ xhttp.status +
" \r\n responseXML = "+ xhttp.responseXML + " \r\n responseText= "+
xhttp.responseText);
var myXml=xhttp.responseXML;
//.... do stuff with myXML variable....
}
The alert statements shows: "2nd in getData...
xhttp.readystate = 4
xhttp.status = 0
xhttp.responseXML = null
responseText = blank"
As I stated, I can hit on the web service indicated in the url and receive an XML document without a problem.
I have executed this same code in both FireFox and IE on two different machines giving me the same problem, so I'm thinking the problem is either in my code or the way the web site is responding to my request.
Any suggestions is certainly appreciated. Thanks to all for your time.
It looks like you are attempting to make a cross-site request and that's the problem. Cross-site requests are not possible with XmlHttp.

How to read a text file from server using JavaScript?

On the server, there is a text file. Using JavaScript on the client, I want to be able to read this file and process it. The format of the file on the server cannot be changed.
How can I get the contents of the file into JavaScript variables, so I can do this processing? The size of the file can be up to 3.5 MB, but it could easily be processed in chunks of, say, 100 lines (1 line is 50-100 chars).
None of the contents of the file should be visible to the user; he will see the results of the processing of the data in the file.
You can use hidden frame, load the file in there and parse its contents.
HTML:
<iframe id="frmFile" src="test.txt" onload="LoadFile();" style="display: none;"></iframe>
JavaScript:
<script type="text/javascript">
function LoadFile() {
var oFrame = document.getElementById("frmFile");
var strRawContents = oFrame.contentWindow.document.body.childNodes[0].innerHTML;
while (strRawContents.indexOf("\r") >= 0)
strRawContents = strRawContents.replace("\r", "");
var arrLines = strRawContents.split("\n");
alert("File " + oFrame.src + " has " + arrLines.length + " lines");
for (var i = 0; i < arrLines.length; i++) {
var curLine = arrLines[i];
alert("Line #" + (i + 1) + " is: '" + curLine + "'");
}
}
</script>
Note: in order for this to work in Chrome browser, you should start it with the --allow-file-access-from-files flag. credit.
Loading that giant blob of data is not a great plan, but if you must, here's the outline of how you might do it using jQuery's $.ajax() function.
<html><head>
<script src="jquery.js"></script>
<script>
getTxt = function (){
$.ajax({
url:'text.txt',
success: function (data){
//parse your data here
//you can split into lines using data.split('\n')
//an use regex functions to effectively parse it
}
});
}
</script>
</head><body>
<button type="button" id="btnGetTxt" onclick="getTxt()">Get Text</button>
</body></html>
You need to use Ajax, which is basically sending a request to the server, then getting a JSON object, which you convert to a JavaScript object.
Check this:
http://www.w3schools.com/ajax/tryit.asp?filename=tryajax_first
If you are using jQuery library, it can be even easier:
http://api.jquery.com/jQuery.ajax/
Having said this, I highly recommend you don't download a file of 3.5MB into JS! It is not a good idea. Do the processing on your server, then return the data after processing. Then if you want to get a new data, send a new Ajax request, process the request on server, then return the new data.
Hope that helps.
I used Rafid's suggestion of using AJAX.
This worked for me:
var url = "http://www.example.com/file.json";
var jsonFile = new XMLHttpRequest();
jsonFile.open("GET",url,true);
jsonFile.send();
jsonFile.onreadystatechange = function() {
if (jsonFile.readyState== 4 && jsonFile.status == 200) {
document.getElementById("id-of-element").innerHTML = jsonFile.responseText;
}
}
I basically(almost literally) copied this code from http://www.w3schools.com/ajax/tryit.asp?filename=tryajax_get2 so credit to them for everything.
I dont have much knowledge of how this works but you don't have to know how your brakes work to use them ;)
Hope this helps!
It looks like XMLHttpRequest has been replaced by the Fetch API. Google published a good introduction that includes this example doing what you want:
fetch('./api/some.json')
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
However, you probably want to call response.text() instead of response.json().
Just a small point, I see some of the answers using innerhtml. I have toyed with a similar idea but decided not too, In the latest version react version the same process is now called dangerouslyinnerhtml, as you are giving your client a way into your OS by presenting html in the app. This could lead to various attacks as well as SQL injection attempts
You need to check for status 0 (as when loading files locally with XMLHttpRequest, you don't get a status and if it is from web server it returns the status)
function readTextFile(file) {
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, false);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var allText = rawFile.responseText;
alert(allText);
}
}
}
rawFile.send(null);
}
For device file readuing use this:
readTextFile("file:///C:/your/path/to/file.txt");
For file reading from server use:
readTextFile("http://test/file.txt");
I really think your going about this in the wrong manner. Trying to download and parse a +3Mb text file is complete insanity. Why not parse the file on the server side, storing the results viva an ORM to a database(your choice, SQL is good but it also depends on the content key-value data works better on something like CouchDB) then use ajax to parse data on the client end.
Plus, an even better idea would to skip the text file entirely for even better performance if at all possible.

Get Url Source, through javascript ajast

I've been experimenting with Ajast and it's very useful for getting remote URL sources etc. In the below example it bypasses same-domain-policy and gets "Hello World !", but I cannot recreate this when I change it to google.com.
<html>
<head>
<script type="text/javascript" src="http://ajast.org/ajast/ajast.js"></script>
<script id="TestScript" Language="javascript">
function test()
{
var xmlhttp = new AJAST.JsHttpRequest();
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState==4) // 4 = "loaded"
{
if (xmlhttp.status == 200)
document.write(xmlhttp.responseText);
else
alert('ERROR: ' + xmlhttp.status + ' -> ' + xmlhttp.statusText);
}
}
xmlhttp.open("GET", 'http://riffelspot.com/ajast/ajast_full.php', false);
xmlhttp.send();
}
</script>
</head>
<body onload="test();">Please wait...</body>
</html>
</code>
My problem occurs when I change the get url to google.com, can anyone help me? I want JavaScript to fetch the source of a page.
Read the documentation.
AJAST can only be used to send a request to a compatible server-side script.
Basically, it's a non-standard form of JSONP.
I thought that dynamicly loading the script into the DOM would bypass this security feature, like the quote suggests
"The main advantage of AJAST is its ability to make requests to foreign hosts (cross domain) which a standard AJAX request cannot do using a technique known as 'the script tag hack'. "
Where would I be able to find documentation as i dont want to use a JSONP proxy, I would like to request the webpage without signing.

Categories