I have the following code:
xmlDoc=loadXMLDoc("dbbackup.xml");
x=xmlDoc.getElementsByTagName("record");
alert(x);
for (i=0;i<3;i++) {
newel=xmlDoc.createElement("edition");
newtext=xmlDoc.createTextNode("first");
alert("x : "+x[i]);
alert("newtext :"+newtext.nodevalue);
x[i].appendChild(newel);
alert("sd");
}
function loadXMLDoc(dname) {
if (window.XMLHttpRequest) {
xhttp=new XMLHttpRequest();
} else {
xhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.open("GET",dname,false);
xhttp.send();
return xhttp.responseXML;
}
I have created dbbackup.xml in the same location and the XML file looks like:
<sticky>
<record></record>
</sticky>
But after running my script the xml file is not getting updated.
Javascript cannot modify files on disk, it only runs for the client in the client's web browser.
To actually write to and from files on a server, you have to use server-side languages and technologies, like PHP or ASP.
I made this - making XML at client side then using everyday praksis
Mike
function makeSlot() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) showBon(); }
xmlhttp.open("POST","crMakeSlot.php",true);
xmlhttp.send(wrapUp());
}
/***
* make the final transaction - using XML
*/
function wrapUp () {
var transaction = document.implementation.createDocument("","", null);
var operator = document.createElement("operator");
var textblok1 = document.createTextNode(document.getElementById("rText").value);
operator.appendChild(textblok1);
var root = document.createElement("transaction");
root.setAttribute("tstamp", now);
root.setAttribute("sequenceno", zSequenceNo.textContent);
if (parseInt(document.getElementById("zDankort").value) > 0) root.setAttribute("dankort", document.getElementById("zDankort").value);
if (parseInt(document.getElementById("zCash").value) > 0) root.setAttribute("cash", document.getElementById("zCash").value);
if (parseInt(document.getElementById("zCredit").value) > 0) root.setAttribute("credit", document.getElementById("zCredit").value);
if (parseInt(document.getElementById("zCheck").value) > 0) root.setAttribute("check", document.getElementById("zCheck").value);
if (parseInt(document.getElementById("zGiftcard").value) > 0) root.setAttribute("giftcard", document.getElementById("zGiftcard").value);
if (parseInt(document.getElementById("zVoucher").value) > 0) root.setAttribute("voucher", document.getElementById("zVoucher").value);
root.appendChild(operator);
var divObj = document.getElementsByTagName("div");
/***
* when column value is 4, then we have our data complete - next cycle
*/
for (ix = 0; ix < divObj.length; ix++) {
switch (divObj[ix].getAttribute("column")) {
case "1": var row = document.createElement("row"); row.setAttribute("item",divObj[ix].textContent);
case "2": row.setAttribute("price",divObj[ix].textContent);
case "3": row.setAttribute("quantum",divObj[ix].textContent);
case "4": root.appendChild(row);
default: break;
}
}
transaction.appendChild(root);
return(transaction);
}
SomeKidWithHTML is right.
JavaScript is designed to only modify a file, in memory, that is loaded inside a browser framework.
Think of the browser as a sandbox that your kids (html, xml, etc.) can play in. As long as Johnny (xml) is in the sandbox playing, all is well. But if Johnny were allowed to play outside of that sandbox, just think of the havoc that could be done on your machine by websites.
There is NO WAY a JavaScript can permanentally affect a file on your local machine, by itself. It can only play inside the sandbox (locally, it can make calls to Java, or an other API, to affect change, but that's a whole other deal).
JavaScript is client side only. If you expect it to affect a server, it can only do it through calls back to the server. At the server you will need some kind of programming (asp.net, java, php, html, others) to receive and answer that call and do something with it.
JavaScript, by itself, is very powerful... but only inisde the sandbox (browser). For it to affect anything else outside of that browser it must depend on other programs already in place and ready to receive those requests.
And this is all in the name of security, mostly.
You can collect data from the web page in client side and send them to the server (ajax), which will then generate the xml file and send back a link to the file (ajax). Use javascript to generate a download link using the link returned by the server.
This is the way I do to solve the problem in one of my project.
Related
I want to load locally stored data using plain javascript (no jquery for example) and then use it to display it in a table in html. My project structure looks like this:
root
- js
-- main.js
- res
-- data.csv
- index.html
I tried using a XMLHttpRequest, but somehow I get status 0 when trying to load the file and when printing the response text it prints out nothing at all.
The following method is called using window.onload:
var url = "file://../res/data.csv/";
varxmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
console.log(this.responseText);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
I don't think you can access the file system through most browsers.
Even if it worked locally, it wouldn't work as soon as you put your page up on a server. This is because the client will be asking for a file that is local to itself, not the server.
Chrome may have something for you though:
https://www.html5rocks.com/en/tutorials/file/filesystem/
A have a folder filled with files accessible to the end user, and am working on a javascript file to parse through them and deliver them as needed. However, rather than manually updating the list, I'd like the javascript to scan the folder and then list iterate through an array of the files in that folder. Is there a decent way in front-end JS to do this? All solutions I've looked into have turned out to be purely for Node.
For example, say I have a folder structure like so...
/ (Web Root)
|__ /Build_a_card
|__ /Cool pictures
|__ /Summer Pictures
summer_dog.gif
smiling_sun.svg
|__ /Winter Pictures
snowman.png
cat.jpg
And then in the javascript I'd run something like
var image_list = get_list("/Cool Pictures");
build_select_list(image_list);
function get_list(folder_to_look_in){
var the_list = ???
return the_list;
}
...
And then, for example, the JS is run, and after some parsing, the user would see...
<select>
<option value="summer_pictures/summer_dog.gif">summer_dog.gif</option>
<option value="summer_pictures/smiling_sun.svg">smiling_sun.svg</option>
<option value="winter_pictures/snowman.png">snowman.png</option>
<option value="cat.jpg">cat.jpg</option>
</select>
In an insane world, since the individual files in the folder are accessible to javascript, hypothetically I could brute-force every single possible file name in the folder and return success on each one:
function get_list(folder){
var list_of_files = {};
var starting_character = 0;
list_of_files = every_single_option({starting_character}, 0, 40, folder)
}
}
function every_single_option(existing_characters, current_depth, max_depth, folder){
this_string = String.fromCharCode(existing_characters);
if (request_url(this_string, folder)){
there_array[this_string] = this_string;
}
var there_array = {}
var i;
if (current_depth < max_depth){
while (i < 127){
let temp_array = there_array;
temp_array[i] = i;
mix_source(there_array, every_single_option(existing_characters, current_depth + 1, max_depth, folder))
}
}
return there_array;
}
function request_url(url, folder){
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "/" + folder + "/" + url);
oReq.send();
}
function mix(source, target) {
for(var key in source) {
if (source.hasOwnProperty(key)) {
target[key] = source[key];
}
}
}
but as mentioned, doing it that way would be insane (both ridiculously slow and very bad code design, resorting to brute-forcing your own website is just dumb.)
but it does hypothetically prove that there's no reason javascript shouldn't be able to just get a directory listing assuming public permissions. Alternatively, I could make some API with the backend that allows fetching a JSON that lists it, but that's requiring backend code for something that's a frontend process. I'm trying to pull this off with something sane and simple, but the question is... how?
(If you insist on posting a jquery way to do this, please also post a non-jquery way as well as there is no jquery available in my environment.)
So, refusing to admit it's impossible, I engineered a solution that works, and requires no API.
That said, the server has to not be actively blocking the javascript from viewing the directory. In other words, the server hasn't turned indexing off, and the directory doesn't have an index.html or equivalent to rewrite any attempt to index, and the server isn't doing some url-rewriting. In other words, this should work in any server environment that doesn't rewrite or block indexes.
Here's a rough draft (still buggy, needs finished):
var request = new XMLHttpRequest();
request.open('GET', '/my/directory/', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
var resp = request.responseText;
}
};
request.send();
var directory_listing = resp;
var regexp = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i;
var match, files = [];
while ((match = regexp.exec(resp)) != null) {
files.push(match.index);
}
console.log(files);
Building off lilHar's answer, we can use DOMParser to create a shadow-DOM for the directory page we're accessing, and then use that to find any links we need:
// relative path to the desired directory
const directory = "/DIRECTORY-NAME/";
// selector for the relevant links in the directory's index page
const selector = "LINK SELECTOR";
const request = new XMLHttpRequest();
request.open("GET", directory, true);
request.onload = () => {
// succesful response
if(request.status >= 200 && request.status < 400)
{
// create DOM from response HTML
const doc = new DOMParser().parseFromString(request.responseText, "text/html");
// get all links
const links = doc.querySelectorAll(selector);
console.log("Links:", links);
links.forEach(link => {
// do stuff with the links
});
}
};
request.send();
Is there a decent way in front-end JS to do this?
No. Nor is that a way that isn't decent.
The front end can communicate with the server via HTTP or WebSockets.
Neither of those provides any built-in mechanism for exploring a filesystem.
You need the server to provide an API (e.g. a web service) which provides the information you want.
I am working on a simple project which involves loading local .xml file into DOM structure by local .html file. We can assume that .html and .xml file are placed in the same folder on the same computer. Problem is that IE 11 disallows any interaction with local xml file. (SCRIPT5: Access is denied.)
So far i tried this solutions (Solution 1,2 are tested and functional within Mozilla FireFox and Google Chrome, Microsoft Edge has some different problem - see first code snippet):
Synchronous/Asynchronous XMLHttpRequest (async in example)
function loadXMLDoc(doc)
{
try{
xmlhttp = new XMLHttpRequest();
}catch(e){
try {
xmlhttp = new ActiveXObject("MSXML2.XMLHTTP.3.0");
}
catch(e){
try {
xmlhttp = new ActiveXObject("MSXML2.XMLHTTP");
}
catch(e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e) {
alert("XMLHTTP Not Supported On Your Browser");
}
}
}
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200) /*Microsoft edge returns status 0 here */
{
alert(xmlhttp.responseText);
}
};
xmlhttp.open("GET",doc,true);/*IE11 prints "SCRIPT5: Access is denied." into console*/
xmlhttp.send();
}
And JQuery async solution
window.onload = function() {
$.ajax({
url: "output.xml",
aync: true,
success: myHandle,
isLocal:true,
dataType: "xml"
});
}
function myHandle(data) {
alert(data);
}
Third solution consists of simple node.js webserver (see Using node.js as a simple web server)
but this seems to be a too large gun for me.
Also there is a problem that web server has to be start explicitly via cmd / script, but i just want to hit .html and see interpreted xml data.
TL;DR My questions are:
Is there any workaround that makes local .xml files accessible for
IE11?
Why is this "security risk" for IE but not for others?
Note:
Since .xml file can have more Mb, async solutions are prefered for me.
Thank you.
If you're trying to provide the file path as a local path, then it won't work in other browsers as well, using plain javascript, and you may get Cross domain errors. If you have a web server, you can put the file there in the appropriate location, and provide the path as "http://localhost/.../file.xml". This may help.
Well, what I propose as a backup opportunity is to go away a bit from the html + js solution and try XML + XSLT. This should not have any security issues, the only thing that changes for you - you don't need to open index.html but you'll need to open output.xml in your browser.
Also, you would need to add to your XML file the pointer to your XSLT file, see e.g. here how to do that.
Once you loaded your XML and processed it with XSLT you have the same HTML with the same JavaScript, but all data is already rendered. XSLT is quite powerful and I am sure it will fulfill all your requirements
I'm trying to read in a local text file to perform functions like counting syllables, characters etc.,
I am trying to do this by doing:
var txtFile = new XMLHttpRequest();
txtFile.open("GET", "file://path/to/my/file.txt", true);
txtFile.onreadystatechange = function() {
if (txtFile.readyState === 4) { // Makes sure the document is ready to parse.
if (txtFile.status === 200) { // Makes sure it's found the file.
allText = txtFile.responseText;
//lines = txtFile.responseText.split("\r\n"); // Will separate each line into an array
} //"\r\n"
}
}
when I try to log 'txtFile' to the command line it prints [ObjectHtmlRequest], how do i look at what i'm loading and consequently iterate over it?
I also get an error message when i try doing this piece of code
var text = txtFile
//$(this).val();
//document.text_input.my_text.value = newtext;
var words = new Array(text.replace(/\s/g, ' ').split(' '));
which worked before, but i'm guessing it's not now because i'm no longer working with text
Most browsers won't allow JavaScript to use the local filesystem. Chrome definitely won't, I'm not sure about Firefox and the others.
What I do in that case is either :
Use a local web server based on the local directory if the file you want to read is static. I usually start it with python -mhttp.server (Python 3) or python -mSimpleHTTPServer (Python 2).
Use the latest HTML5 File API if you want to let the user choose the file. More information here.
EDIT: Well, what I said isn't entirely true. Chrome allows you to use local files, but you have to start it on the command line with a special switch (--allow-file-access-from-files), and frankly, it's a bother and is only really intended for development. Don't rely on it for anything in production!
I think until v5 of Google Chrome the below code worked. Now in the latest version I get the following error when opening my webpage locally:
"XMLHttpRequest cannot load file:///C:/Temp/Course.xml. Cross origin requests are only supported for HTTP."
The Javascript code:
function getXmlDocument(sFile) {
var xmlHttp, oXML;
// try to use the native XML parser
try {
xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", sFile, false); // Use syncronous communication
xmlHttp.send(null);
oXML = xmlHttp.responseXML;
} catch(e) {
// can't use the native parser, use the ActiveX instead
xmlHttp = getXMLObject();
xmlHttp.async = false; // Use syncronous communication
xmlHttp.resolveExternals = false;
xmlHttp.load(sFile);
oXML = xmlHttp;
}
// return the XML document object
return oXML;
}
// get the best ActiveX object that can read XML
function getXMLObject() {
// create an array with the XML ActiveX versions
var aVersions = new Array("Msxml2.DOMDocument.6.0", "Msxml2.DOMDocument.3.0");
// loop through the array until we can create an activeX control
for (var i=0; i<aVersions.length; i++) {
// return when we can create the activeX control
try {
var oXML = new ActiveXObject(aVersions[i]);
return oXML;
}
catch(e) {
}
}
// could not create an activeX, return a null
return null;
}
I really don't want to be forced to open the web page from a web server every time.
Local file access is disabled by default for security reasons. Try starting Google Chrome from the command line with the argument --allow-file-access
It would be more secure if you just start a local webserver and fetch your html and xml from localhost.
You can easily avoid deploying of the files by just let the server serve the contents of a local folder in which you place your xml.
This way you avoid
having to start chrome in an unsecure mode
having problems when you later deploy your app to a server on the internet
server to go is an example for an easy to install webserver http://www.server2go-web.de/