I have a text file (here big_buck_bunny_trailer_480p.srt), "sibling" to a html page (so when I run the html page locally, it is a local file - when I run it on server, it is a remote file) - the directory structure is:
.
├── big_buck_bunny_trailer_480p.srt
└── ttt.html
I'm trying to read the text file using XMLHttpRequest; that succeeds fine, and I can get the string content of the text file. But when I try to create a Blob out of it, in Firefox 60 console I get "unavailable".
This is my test file, ttt.html:
<script type="text/javascript">
function reqListener () {
console.log(this.responseText);
var myblob = new Blob([this.responseText], {
type: 'text/plain'
});
console.log(myblob);
}
var oReq = new XMLHttpRequest(); // "To read files that are siblings of the HTML document, use XMLHttpRequest"
oReq.addEventListener("load", reqListener);
oReq.open("GET", "big_buck_bunny_trailer_480p.srt");
oReq.send();
</script>
When I run it in Firefox 60, console prints out:
1 ttt.html:4:3
00:00:00,005 --> 00:00:03,800
The peach open movie project presents
(...)
<unavailable> ttt.html:8:3
The character encoding of the HTML document was not declared. ...
XML Parsing Error: syntax error
Location: file:///tmp/test/big_buck_bunny_trailer_480p.srt
Line Number 1, Column 1: big_buck_bunny_trailer_480p.srt:1:1
So, I get the string right - but why is the Blob <unavailable>? How can I get a Blob out of this string?
Bonus question: I get why the warning "The character encoding of the HTML document was not declared" appears, - after all, I don't even have <html> in my html file. BUt why does XML Parsing Error: syntax error appear? All I asked for was to read this file, not parse it? If the parsing is automatic, can I prevent it somehow - all I need are the string contents?
EDIT: reduced the example to this:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript">
var myblob = new Blob([window.btoa("Hello world")], {
type: 'text/plain'
});
console.log(myblob);
</script>
</head>
</html>
... and accessed it by using python -m SimpleHTTPServer, so via http://127.0.0.1:8000/ttt.html; and the only printout I get in the console is:
<unavailable> ttt.html:22:3
So, how do I get an actual blob from a string?
your html tags may interrupt the xml parsing. That's why its throwing Syntax Error. That kind of error is very common in JSON or XML parsing. Before create Blob, encode the Response Data.
Try this,
new Blob([window.btoa(this.responseText)], {
type: 'text/plain'
});
And also, When you retrieve the data from Blob. You need to decode using window.atob().
There are many things that browsers won't allow to happen over the file:// protocol. This is probably one of them.
Instead of running it over the file:// protocol, it is better to use a small local server to run it over. There are lots of them out there, so lots of options. Many IDEs even have them built in. I like to write a quick 10-line version with Express and Node. Whichever you chose, it'll just serve up static files for you over the http:// protocol so you can avoid these issues.
Got it, finally - turns out, if you watch console.log(myblob); in Firefox 60 Browser Console (Ctrl-Shift-J, the one in standalone window), then you get <unavailable>; but if at the same time, you observe the Web Console (Ctrl-Shift-K, sits in a tab near the Inspector of Inspect Element right-click), then you get a proper printout; see .gif:
Here it is accessed via a local server, so through http://127.0.0.1:8000/ttt.html - but accessing it locally via file:// protocol yields the exact same results (the blob can be seen in Web console to be instantiated fine, regardless of protocol).
For reference, here is the final ttt.html I used while capturing the .gif video:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript">
function reqListener () {
console.log(this.responseText.substr(0,60)+"...");
var myblob = new Blob([window.btoa(this.responseText)], {
type: 'text/plain'
});
console.log(myblob);
}
var oReq = new XMLHttpRequest(); // "To read files that are siblings of the HTML document, use XMLHttpRequest"
oReq.overrideMimeType("text/plain");
oReq.addEventListener("load", reqListener);
oReq.open("GET", "big_buck_bunny_trailer_480p.srt");
oReq.send();
</script>
</head>
</html>
Related
I am trying to read a file in Java script. I am using XAMPP server, all the files are in the htdocs folder. But when I try to read a file from other directory its not working.
Error:
NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
request.send(null);
JavaScript:
<!DOCTYPE html>
<html>
<body>
<textarea id="box" rows="4" cols="50"> </textarea>
<script>
//get the contents of the text file START
//Make sure in the JsonData.txt file, after each line there should not be any space ie when you click RIGHT arrow at the end of each line the cursor should go to next line beginning.
function FileHelper()
{}
{
FileHelper.readStringFromFileAtPath = function(pathOfFileToReadFrom)
{
var request = new XMLHttpRequest();
request.open("GET", pathOfFileToReadFrom, false);
request.send(null);
var returnValue = request.responseText;
return returnValue;
}
}
var pathOfFileToRead = "file://d:/sampleData.txt";
var contentsOfFileAsString = FileHelper.readStringFromFileAtPath
(
pathOfFileToRead
);
var contents_value = contentsOfFileAsString;
alert(contents_value);
document.getElementById("box").value = contents_value;
//document.getElementById("demo").innerHTML = contents_value;
//get the contents of the text file STOP
</script>
</body>
</html>
In the JS 'pathOfFileToRead=filepath' if I keep the file in the same htdocs directory its working fine, but not working if I give local directory path like I have given in the above JS.
You're using javascript running in the browser. You can't use the file:// protocol to read your file, and you can't use drive letters.
You can still do what you want to do though. You need to reference your file with an url and call it with http://. (You know the difference ?! An url has a domain name or ip address pointing to a web root, then perhaps a port number, then forward slashes separating each folder below the web root. A windows path has a drive letter, then backslashes separating each folder.)
There are tons of litte things to improve in your script. I would start with removing the pair of empty braces on line 2. Then, I don't think anyone uses xmlhttp in synchronous mode. You should really be using asynch with callbacks, and checking for success (200) before doing your business.
I have MqttConnect.js file and mqttws31.js lib . I have to mqttws31.js all source code include my MqttConnect.js file, How it possible?.
when I copy everything from mqttws31.js and past mqttconnect.js file .that time this error occur:
ReferenceError: Messaging is not defined
if I try this way it is working fine :
<head>
<meta charset="UTF-8">
<title>Title of the document</title>
<script src="http://www.hivemq.com/demos/websocket-client/js/mqttws31.js" type="text/javascript"></script>
<script src="MqttJS/MqttConnect.js"></script>
</head>
MqttConnect.js file code :
// Using the HiveMQ public Broker, with a random client Id
var client = new Messaging.Client("broker.mqttdashboard.com",8000, "myclientid_" + parseInt(Math.random() * 100, 10));
//Connect Options
var options = {
timeout: 60,
keepAliveInterval:450,
cleanSession:false,
//Gets Called if the connection has sucessfully been established
onSuccess: function () {
alert("Connected:");
},
//Gets Called if the connection could not be established
onFailure: function (message) {
alert("Connection failed -: " + message.errorMessage);
}
};
function Connect(){
try {
client.connect(options)
}
catch(err){
alert(err.message);
}
}
mqttws31.js code:
http://www.hivemq.com/demos/websocket-client/js/mqttws31.js
UPDATE
where I want use this , there have no html page
This may be due to a quirk of how JavaScript loads. You can find a good example of how it should be done in this answer.
The quick answer is to place the loading of both JavaScript files into the body of the HTML document hosting them, with the MQTT library above your script.
Do NOT just copy the library into your own file, that's very poor form and a copyright violation if you don't credit the library's source properly.
Copy content of mqttws31.js into MqttConnect.js at the top (not at the bottom) and then load MqttConnect.js file:
<head>
<meta charset="UTF-8">
<title>Title of the document</title>
<script src="MqttJS/MqttConnect.js"></script>
</head>
I tried this myself, I am not getting any error. (window is undefined)
There is a dependency between the two files, that is, there is code in MqttConnect.js which needs the code in mqttws31.js in order to work properly. So I'm assuming you pasted the contents of mqttws31.js at the end of MqttConnect.js. Pasting the contents of mqttws31.js at the beginning of MqttConnect.js should fix this. Your MqttConnect.js should look like
// Contents of mqttws31.js ...
// Contents of MqttConnect.js ...
I had a coding interview quiz for front-end working with JSON and whatnot. I submitted my file but I'd just like to learn what I was missing.
And one of the reqs was Should not require a web server, and should be able to run offline..
I used jQuery and used $.getJSON() to get the data from the .JSON file. I threw it up on my WAMP localserver and it worked flawlessly across all three major browsers (IE, Firefox, Chrome). Then I moved that project to Desktop, so essentally, without a LOCALSERVER.
On Firefox 30.0, it worked great. No problems.
Oon Google Chrome, I know you can't access local files without a web server...
On Internet Explorer 11, however... it didn't work. Why?
Here is what I am using. It's not complex.
function loadTasks() {
console.log("Loading tasks...");
$.getJSON("data.json", function(result) {
$.each(result, function(i, task) {
$("#load_tasks").append(
"<div class='row'><span class='data-task'>" + task.name +
"</span> <span class='data-date'>" + task.date +
"</span> <span class='data-name'>" + task.assigned +
"</span> </div>");
});
});
}
and here is data.json
This seems to be a bug in jQuery. This bug has been reported to jQuery. The bugs status is fixed. But it seems, the bug is still at large.
Explanation
Generally in IE, ajax is implemented through ActiveXObjects. But in IE11, they made some tweaks to ActiveXObject implementation that if we try to do the following:
typeof(window.ActiveXObject)
instead of returning 'function', as it is said in IE docs, it returns undefined. jQuery used to use this to switch between xhr in normal browsers and between one in IE. Since the check evaluates to undefined, code used to create xhr object in normal browsers is run.(which of-course is a bug, strangely, for non-local files it working fine).
In a bug filed to bugs.jquery.com, the bug reporter asks,
To fix the problem it's enough to change the condition: use
"window.ActiveXObject !== undefined ?" instead of
"window.ActiveXObject ?"
jQuery developers does try to fix this with this commit, but the comment under the commit says its still not fixed and also suggests a possible way to approach this problem.
var activex; // save activex somewhere so that it only need to check once
if ( activex === undefined )
try {
new ActiveXObject("MSXML2.XMLHTTP.3.0");
activex = true;
} catch (e) {
activex = false
}
xhr = activex ? createActiveXHR() : createStandardXHR();
I tried running your code in my machine and it works fine in IE.
However if this is not running in your machine there should be some issue with IE settings. Apart from this if you want to read local file you can try the below code to resolve this issue for IE
function showData(){
function getLocalPath(fileName/*file name assuming in same directory*/){
// Remove any location or query part of the URL
var directoryPath = window.location.href.split("#")[0].split("?")[0];
var localPath;
if (directoryPath.charAt(9) == ":") {
localPath = unescape(directoryPath.substr(8)).replace(new RegExp("/","g"),"\\");
}
localPath = localPath.substring(0, localPath.lastIndexOf("\\")+1)+fileName;
console.log(localPath);
return localPath;
}
var content = null;
try {
var fileSystemObj = new ActiveXObject("Scripting.FileSystemObject");
var file = fileSystemObj.OpenTextFile(getLocalPath("data.json"),1);
content = file.ReadAll();
file.Close();
} catch(ex) {
console.log(ex);
}
console.log(content);
}
showData();
Run your html file in browser from file path and try running above function in console. It will output the content of json file in console.
You can create a wrapper for above code to use in XHR request. Let me know if you need help in integrating this with jQuery AJAX request.
What you we're missing was the use of appCache,
<html manifest="example.appcache">
in your HTACCESS add
AddType text/cache-manifest .appcache
inside example.appcache
CACHE MANIFEST
data.json
index.php
someimage.png
# continue for all the file needed for the web site to work
This means that once you have connected and downloaded the content once it's not needed again. on another note you not supposed to be able to access a file:// URI though XHR/ajax as there is no way to send the content if you wanted it offline you could have just embedded the content of the json file into you code as a string and just use var jsonStr = '{}'; var jsonObj = JSON.parse(jsonStr); where jsonStr is you code. this would have meant no connections to the server as there would be no ajax/XHR request
jQuery .getJSON uses ajax. http://api.jquery.com/jquery.getjson/
.ajax uses a XMLHttpRequest
The web security of chrome and other browsers block XMLHttpRequest to local files because it is a security issue.
Via Security in Depth: Local Web Pages
http://blog.chromium.org/2008/12/security-in-depth-local-web-pages.html
You receive an email message from an attacker containing a web page as
an attachment, which you download.
You open the now-local web page in your browser.
The local web page creates an iframe whose source is
https://mail.google.com/mail/.
Because you are logged in to Gmail, the frame loads the messages in
your inbox.
The local web page reads the contents of the frame by using JavaScript
to access frames[0].document.documentElement.innerHTML. (An Internet
web page would not be able to perform this step because it would come
from a non-Gmail origin; the same-origin policy would cause the read
to fail.)
The local web page places the contents of your inbox into a
and submits the data via a form POST to the attacker's web server. Now
the attacker has your inbox, which may be useful for spamming or
identify theft.
The solution for data which does not need same-origin policy security, is padded json. Since jsonp is not a secure format for data. Jsonp does not have the same-origin policy.
/* secured json */
{
"one": "Singular sensation",
"two": "Beady little eyes",
"three": "Little birds pitch by my doorstep"
}
/* padded json aka jsonp */
Mycallback ({
"one": "Singular sensation",
"two": "Beady little eyes",
"three": "Little birds pitch by my doorstep"
});
Since with jsonp the json is wrapped in a valid javascript function it can be opened the same way as any one would add any javascript to a page.
var element = document.createElement("script");
element.src = "jsonp.js";
document.body.appendChild(element);
And your callback processes the data,
function Mycallback(jsondata) {
}
This is functionally the same as a ajax request but different because it is a jsonp request, which is actually easier.
jQuery libs do directly support jsonp as well http://api.jquery.com/jquery.getjson/ See the example using Flickr's JSONP API; unless one was aware of the dual standards they may not even notice that jsonp is being used.
(function() { /* jsonp request note callback in url, otherwise same json*/
var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
$.getJSON( flickerAPI, {
tags: "mount rainier",
tagmode: "any",
format: "json"
})
.done(function( data ) {
$.each( data.items, function( i, item ) {
$( "<img>" ).attr( "src", item.media.m ).appendTo( "#images" );
if ( i === 3 ) {
return false;
}
});
});
})();
Local access to json can be enabled but it is done differently depending on browswer.
Use --allow-file-access-from-files to enable it in chrome. https://code.google.com/p/chromium/issues/detail?id=40787
FYI: they are working on encripted json https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-encryption-08 I am fairly certain that there will be no method of using this locally the intention is to make it really, really secure.
Source: https://stackoverflow.com/a/22368301/1845953
Posting the answer just in case somebody else runs into it. In my case
IE was loading a version of jquery that apparently causes "JSON
undefined" error. Here is what I did to solve it:
<!--[if lt IE 9]>
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<![endif]-->
<!--[if gte IE 9]><!-->
<script src="http://code.jquery.com/jquery-2.0.3.js"></script>
<!--<![endif]-->
The latest one is jquery 2.1.1: direct link but it says:
(IE <9 not supported)
So I guess jquery 1.11.1: direct link
And I found out you can develop ajax and jquery stuff in Chrome on local files if you use Chrome with this flag: --allow-file-access-from-files (source)
<meta http-equiv="X-UA-Compatible" content="IE=edge">
Try adding this meta tag and check in IE
Here's a working solution.
I've included handlebars because it's cleaner.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JSON TEST</title>
</head>
<body>
<div id="load-tasks">
</div>
<script src="jquery.min.js"></script>
<script src="handlebars.min.js"></script>
<script id="tasks-template" type="text/x-handlebars-template">
{{#each .}}
<div class="row">
<span class="data-task">
{{this.name}}
</span> <span class="data-date">
{{this.date}}
</span> <span class="data-name">
{{this.assigned}}
</span>
</div>
{{/each}}
</script>
<script>
$(function () {
var loadTasksContainer = $('#load-tasks'),
tasksTemplate = Handlebars.compile($('#tasks-template').html());
$.ajax({
type: "GET",
url: "data.json",
dataType: "json",
cache: false,
success: function (data) {
var html = tasksTemplate(data);
loadTasksContainer.append(html);
},
error: function (xhr, status, error) {
//log error and status
}
});
});
</script>
</body>
</html>
Using JSONP you could make this work for all browsers with or without a web server or even cross domain.
Example data.jsonp file:
loadTasks([
{name:"Task 1", date:"Date 1", assigned:"John Doe"},
{name:"Task 2", date:"Date 2", assigned:"Jane Doe"}
]);
Then on your page just load the data.jsonp using a script tag:
<script>
function loadTasks(tasks) {
$.each(tasks, function (i, task) {
$("#load_tasks").append(
"<div class='row'><span class='data-task'>" + task.name +
"</span> <span class='data-date'>" + task.date +
"</span> <span class='data-name'>" + task.assigned +
"</span> </div>");
});
}
</script>
<script src="data.jsonp"></script>
Try including an error callback ; jqxhr.responseText may still contain data.json .
data.json
{"data":{"abc":[123]}}
json.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="jquery-1.11.1.min.js"></script>
<script type="text/javascript">
$(function() {
$.getJSON(document.location.protocol + "data.json")
.then(function(data, textStatus, jqxhr) {
var response = JSON.parse(data);
console.log(textStatus, response);
}
// `error` callback
, function(jqxhr, textStatus, errorThrown) {
var response = JSON.parse(jqxhr.responseText);
console.log(textStatus, errorThrown, response);
$("body").append(response.data.abc);
});
})
</script>
</head>
<body>
</body>
</html>
Dealing with this problem will lead you to anywhere. It is a difficult task and it could be easily solved using any http server.
If your problem is that it is difficult to set up one, try this:
https://www.npmjs.org/package/http-server
On your shell you go to the directory where are your files and then you just type
http-server ./ -p 12345
where 12345 can be changed by any valid and not already used port of your choice.
I have a small html/javascript webpage that I want to run in a browser offline.
In the same way the page can include an image or a css file and use it while offline, I want to include a 3mb spreadsheet that the javascript reads into a 2d-array, and I'm hoping for something that would work on IE8 as well as modern browsers.
C:\Folder\index.html
C:\Folder\code.js
C:\Folder\picture.png
C:\Folder\spreadsheet.csv
I've found multiple methods online like
<script src="jquery-csv.js"></script>
var table = $.csv.toArrays("spreadsheet.csv");
or
d3.text('spreadsheet.csv', function(error, _data){
var table = d3.csv.parseRows(_data);
});
or
$(document).ready(function() {
$.ajax({
type: "GET",
url: "data.txt",
dataType: "text",
success: function(data) {processData(data);}
});
});
But I tend to get same-origin policy errors such as:
XMLHttpRequest cannot load file://data.txt. Received an invalid response. Origin 'null' is therefore not allowed access.
Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match.
I can't seem to get these to work offline. How could I accomplish this?
Edit:
I'm managed to get the following to work for a text file only on Firefox using the CSVToArray function found here, which is pretty sluggish with a file of this size, and a hidden iframe.
Ultimately, it would be preferable if this was capable of running on IE8, and if I used a csv rather than a txt file, but at least it's a start.
<iframe style="display:none;" id='text' src = 'file.txt' onload='read_text_file()'>
</iframe>
<script type="text/javascript" >
function read_text_file() {
var text = document.getElementById('text').contentDocument.body.firstChild.innerHTML;
var table = CSVToArray(text);
}
For IE8 I managed to get this to work on a small scale but with the 3mb file it will occasionally crash the browser and will always accost the user with both a ton of warning messages that activex is being used and a wave of warnings that the script will slow down the computer.
window.onLoad = readFileInIE("file.csv");
function readFileInIE(filePath) {
try {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var file = fso.OpenTextFile(filePath, true);
var text = file.ReadAll();
var table = CSVToArray(text);
file.Close();
return fileContent;
} catch (e) {
if (e.number == -2146827859) {
alert('Unable to access local files due to browser security settings. ' +
'To overcome this, go to Tools->Internet Options->Security->Custom Level. ' +
'Find the setting for "Initialize and script ActiveX controls not marked as safe" and change it to "Enable" or "Prompt"');
}
}
}
This might not work in IE8, but the HTML5 API is really useful for this. Just use:
window.onload = function() {
var fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', function(e) {
var file = fileInput.files[0];
var textType = //format you'd like to recieve;
if (file.type.match(textType)) {
var reader = new FileReader();
reader.onload = function(e) {
// apply magic here
}
reader.readAsText(file);
}
else
{
fileDisplayArea.innerText ="Sorry matey, can't help you with that filetype."
}
});
}
Then after that, a simple .html file that looks like this would do the trick:
<html lang="en">
<head>
<script src="script.js"></script>
</head>
<body>
<div id="page-wrapper">
<div>
<input type="file" id="fileInput">
</div>
<pre id="fileDisplayArea"></pre> //display any output here
</div>
</body>
</html>
It's not quite clear what you want to do.
Using jQuery it's possible to modify events that happen in the DOM. Using this you could potentially save the source code when you're done making changes. You would then need to replace your current source code with the saved code to use the changes the next time you open up the page. However, this would be a very laborious process and there are likely a number of better ways to accomplish what you want to do depending on what that is.
Also, in regards to Shota's post. You can't use AJAX unless you have a server running in the background. If you decide to set the system up on a server there are a number of options for accomplishing what you want.
My comment become too long.
You can't include data files in the same way as media. The easiest way would be to preprocess the csv into a js array and then include the csv like js <script src="mydata.csv.js"></script>.
By offline you mean local files and not public? The first suggestion would be to upgrade your browser. It doesn't quiet make sense if its a local file supporting all major browsers. Sorry I'm sure you have reasons why you can't. But upgrading would get around the non Ecmascript 5 support in ie8.
To get around the cross origin policy you'd have to run your file on a local webserver. So your html page would be on something like localhost:8080 and your csv localhost:8080/mydata.csv this gives privileges to the html to allow access to the csv file as they're now on the same domain. D3, jquerycsv should now work. Its a big security risk allowing any html file to access the filesystem freely.
If a local server isn't an option. You have to select the file each time you load with an input field. This grants the browser permissions to access this file.
After selecting the file, to read the contents for the main browsers (with Ecma5) look into FileReader on MDN, and an example of use can be found here. For ie8 + 9 there is VBscript support to read files. You can use VB just like JS using <script type="text/vbscript"></script>
If you really want to access local resources from a sever page then you need also a local page that allows the access. A local HTML page inside an <iframe> could read the text file and post contents to the main page via window.postMessage().
There might also be a way with HTML5 iframes and the sandbox attribute, but not in IE9 and below.
see:
https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
As you have realized, any AJAX-based solution will be affected by security restrictions for local file access. Instead of finding browser-specific workarounds, you could go the JSONP way which avoids AJAX.
This would require you to pre-process your CSV data and save it in a more JS-friendly format. But this would be a good idea anyway, as native JS parsing is likely to perform better than a CSV parser implemented in JS.
It could look roughly like this:
index.html
</head>
<body>
<div id="page-wrapper">
<div>
<input type="file" id="fileInput">
</div>
<pre id="fileDisplayArea"></pre> <!-- display any output here -->
</div>
<script src="script.js"></script>
<script src="data.js"></script>
</body>
</html>
script.js
function processData(data) {
// Your logic
// (will be called once data.js is loaded)
}
data.js
processData([
["your", "data"]
]);
I am trying to learn how to read into a web page data in an XML file. This is a static HTML page. I do not want a web server and I cannot use Ajax. The XML file is local (in the same directory as the HTML file). I want this to work in a Chrome browser.
What I need to do is:
Read the XML file on the page onLoad event.
Use innerHTML to insert the XML data into a div.
My problem is in reading the XML file. All of the examples I have found I think will only work if there is a web server running, which I have to avoid.
If you're reading another file the only way to do that with front end JS is another request (ajax). If this were node.js it would be different because node can access the filesystem. Alternatively if you get the xml into a javascript string on the same page, you can manipulate it. There are a number of good libraries (jquery's parseXML).
Original answer here: https://stackoverflow.com/a/48633464/8612509
So, I might be a little late to the party, but this is to help anybody else who's been ripping his/her hair out looking for a solution to this.
First of all, CORS needs to be allowed in the browser if you're not running your HTML file off a server. Second, I found that the code snippets most people refer to in these kind of threads don't work for loading local XML-files. Try this (example taken from the official docs):
var xhr = new XMLHttpRequest();
xhr.open('GET', 'file.xml', true);
xhr.timeout = 2000; // time in milliseconds
xhr.onload = function () {
// Request finished. Do processing here.
var xmlDoc = this.responseXML; // <- Here's your XML file
};
xhr.ontimeout = function (e) {
// XMLHttpRequest timed out. Do something here.
};
xhr.send(null);
The method (1st arg) is ignored in xhr.open if you're referring to a local file, and async (3rd arg) is true by default, so you really just need to point to your file and then parse the result! =)
Good luck!
Since you're only targeting Chrome, you could take a look at the File API. You'd have to prompt the user to select the file or drop it into a specific area of the page though, which might be something you'd rather avoid, or not. The following HTML5 Rocks article should help.
Assuming the HTML, XML and browser are all on the same machine, you might try using an Iframe in the HTML that references the XML using a URL like file:\.
You could do something like this:
<html>
<head>
<script type="text/javascript">
//If using jQuery, select the tag using something like this to manipulate
//the look of the xml tags and stuff.
$('#xframe').attr('style', 'thisxmltag.....');
</script>
</head>
<body>
...
<frame id="xframe" src="the_xml_doc"></src>
</body>
</html>
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET", file_Location, false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML;
document.getElementById(your_div_id).value =
xmlDoc.getElementsByTagName(The_tag_in_xml_you_want_to_display)
[0].childNodes[0].nodeValue;
Works with IE11
<head>
// To be hidden with a better method than using width and height
<OBJECT id="data1" data="data.xml" width="1px" height="1px"></OBJECT>
// to work offline
<script src="lib/jquery-2.2.3.min.js"></script>
</head>
<body>
<script>
var TheDocument = document.getElementById("data1").contentDocument;
var Customers = TheDocument.getElementsByTagName("myListofCustomers");
var val1 = Customers[0].getElementsByTagName("Name")[0].childNodes[0].nodeValue;