JavaScript Read File Without Using Input

Javascript read file without using input

You simply can't do what you are trying to do. Setting the path for an input element through Javascript is not possible, as a security measure. Please check here: How to resolve the C:\fakepath?

How to read file client-side without using a file input?

client side doesn't have access to manage file system, you can read file with input but cannot write or delete from client side. it is only possible with a backend application written in node js or java, from their you can expose those services and call it from client side through http requests.

Can I read a text file without using the FileReader file choice option

You can use the XMLHttpRequest to load a text file. In the example below the DIV named dummy will receive the loaded text. But instead you could also place the http.responseText into a var for further processing.

    <div id="test">dummy</div>
<input id="reset" type="button" value="reset" onMouseUp="resetDIV()" />
<input id="load" type="button" value="load unsafe" onMouseUp="httpRequest('http://yourserver/yourpath/hello.txt')" />
<input id="load" type="button" value="load safer" onMouseUp="httpRequestByID(1)" />
    const test = document.getElementById('test');
const http = new XMLHttpRequest();

function resetDIV() {
test.innerHTML = 'dummy';
}

const httpResult = function() {
console.log(http);
test.innerHTML = http.responseText;
}

function httpRequest(_url) {
// hacker unsafe because if a hacker finds a way to add or modify an element in the DOM and call your function with his own injected URL he can look for files you don't want others to see.
http.open('GET', _url);
http.onloadend = httpResult;
http.send();
}

function httpRequestByID(_fileNum) {
// a little safer function it is when the urls are hard typed and you can only reference by a file number
if((typeof _fileNum)=='number' && _fileNum>0 && _fileNum<3){
if(_fileNum===1){http.open('GET', 'http://yourserver/yourpath/hello.txt');}
if(_fileNum===2){http.open('GET', 'http://yourserver/yourpath/other.txt');}
http.onloadend = httpResult;
http.send();
}else{
alert('httpRequestByID received an invalid argument');
// nothing more should happen
}
}

Reading from text file without using event in javascript

File loading from a user's operating system has to be triggered by some form of user-event, save for getting a file object from a canvas element (this can be generated directly).

As this excerpt from MDN states:

File objects may be obtained from a FileList object returned as a result of a user selecting files using the element, from a drag and drop operation's DataTransfer object, or from the mozGetAsFile() API on an HTMLCanvasElement.

Allowing a web page the ability to load any file from a user's computer, without the user's intervention or expressed permission, would be a dangerous thing indeed. However, depending on what you can do with your file (or the host environment) you do have some options.


Load file via AJAX/XHTTP

I include source code that I've been using via the file:// protocol, hence the reason for downloading jQuery locally, rather than using any hotlink equivalent. In order to test this you just need to download jQuery and save it in the same directory as this HTML file, and obviously either create a textfile.txt or change the code to point to another file.

NOTE: The file path should be kept within your web root and accessible from your web server under the same host, unless you are running the code from the file:// protocol locally. If you are running over the file:// protocol, you can load a file from anywhere on your machine as long as your browser has permissions to access said file, and you remain accessing via file://.

There is one large difference in loading a file this way (or any of the other methods I mention on the page), to the way you are loading a file in your question. Loading a file via a file selector dialog is sourcing the file from the user's own computer; whereas loading a file via AJAX (or via a script/iframe tag) is sourcing it from the server. Whether or not this defeats your objective would be down to what exactly you are using it for. Never-the-less loading text files is best done via this method, below you will find some other secondary methods that do have their benefits, but also a number of downsides.

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Load a text file</title>
<script src="jquery.js"></script>
<script>
jQuery
.ajax({
url: 'textfile.txt',
dataType: 'text'
})
.error(function(){
console.warn('An error occurred whilst loading the file', arguments);
})
.done(function(res){
jQuery.each(res.split(/\r?\n/g), function(i, v){
jQuery('#output').append('<p>' + v + '</p>');
});
})
;
</script>
</head>
<body>
<h1>Fileload</h1>
<div id="output"></div>
</body>
</html>


Load file via script tag

This option requires that you modify your text file to be wrapped by a small bit of JavaScript, this will then allow you to import its content using an ordinary script tag. Unlike AJAX this is not subject to cross-origin blocking i.e. stackoverflow.com can request the file from gamedev.stackexchange.com. This method also has the benefit of having quite a small footprint.

NOTE: AJAX requests can now reliably get around the cross-origin problems when implementing CORS. However this does usually involve having some control of the server-side.

The downsides to this method are that you have to modify your text files, your text files are parsed as JavaScript (meaning certain higher-order characters can upset older parsers), and you are abusing Function.toString(). If you aren't happy about using comments for a multiline hack you can quite easily modify your text file to implement multiline strings the proper way using string concatenation instead. But once you do that you are getting rather far away from loading anything like a plain text file.

contents of your text file

(typeof loadfile != 'undefined') && loadfile(function(){/*
Place your text file contents here.
We are abusing the JavaScript comment facility
to achieve multiline strings without too much
modification to your original text file.
*/});

script in your main page

<script>
/**
* This function is responsible for receiving the function
* sent by your text file
*/
function loadfile(content){
var text = String(content && content.toString()),
p1 = text.indexOf('/*')+2,
p2 = text.lastIndexOf('*/')
;
console.log(text.substring(p1, p2));
};
</script>
<script src="your-text-file.txt.js"></script>


Load file via an iframe

This option is pretty much what used to be used — if no server-side was available — prior to the prevalence of AJAX. It doesn't really have any benefits over AJAX save for the fact that, if using polling to keep an eye on when the iframe is ready, the code to manage the iframe is smaller and more cross-browser reliable. With AJAX it is generally best to rely on a library (like jQuery) to handle the differences between different environments.

However, that said AJAX gives you a whole lot more ability, and much more interactive feedback as to what has happened when (with better support for events). Relying on polling can be slower/unreliable, but it is your only option with iframes because not all browsers support triggering the correct events, especially when dealing with unexpected data-types.

Here is a script I used to use that I've tidied and updated, just to illustrate the point. This version relies on Object.create so you will need a polyfill for that if you want to use it with older browsers; but as I've stated a number of times... make use of AJAX instead, if you can, if you can't then perhaps your approach needs a rethink.

/**
* Textfile
*
* Allows the loading of a textfile via an iframe or script tag.
*
* Loading via script tag:
*
* textfile.load({
* type: 'script',
* path: 'textfile.txt.js'
* })
* .fail(function(){
* console.log('an error occured!');
* })
* .done(function(res){
* console.log('file loaded', res);
* })
* ;
*
* loading via iframe:
*
* textfile.load({
* type: 'iframe',
* path: 'textfile.txt'
* })
* .fail(function(){
* console.log('an error occured!');
* })
* .done(function(res){
* console.log('file loaded', res);
* })
* ;
*
* NOTE: When loading via a script tag, your text file must be in the
* following format:
*/
(typeof textfile != 'undefined') && textfile.injected('NAME OF YOUR FILE', function(){/*
This is example text content
you can have as many lines as
you want.
*/});
/**
* Once your text file is wrapped with the above the textfile code
* will be notified that the file has been loaded, and it will also
* allow you to have multiline text more easily in JavaScript.
*
* <NAME OF YOUR FILE> should be replaced with your filename to load
* for example textfile.txt.js
*/
var textfile = (function(){

var tf = {

shared: {},

create: function(config){
return tf.prep.apply(Object.create(tf), arguments);
},

prep: function(config){
this.config = config;
this.tag = !this.config.inline
? document.documentElement
: document.scripts[document.scripts.length-1]
;
this.tid = setTimeout(this.bind(this.timeout), this.config.timeout || 5 * 1000);
this.iid = setInterval(this.bind(this.polling), 100);
this.loader = this.config.type === 'script'
? this.script()
: this.frame()
;
this.loader.src = this.config.path;
!this.config.inline
? this.tag.appendChild(this.loader)
: this.tag.parentNode && this.tag.parentNode.insertBefore(this.loader, null)
;
return this;
},

script: function(element){
if ( element ) { return element; }
element = document.createElement('script');
element.type = 'text/javascript';
return element;
},

frame: function(element){
if ( element ) { return element; }
element = document.createElement('iframe');
element.style.position = 'fixed';
element.style.right = '100%';
element.style.bottom = '100%';
element.style.width = '1em';
element.style.height = '1em';
return element;
},

tidyup: function(){
this.loader && this.loader.parentNode.removeChild(this.loader);
return this;
},

loaded: function(res){
this.trigger('done', res);
this.tidyup();
return this;
},

failed: function(){
this.trigger('fail');
this.tidyup();
return this;
},

on: function(name, listener){
!this.listeners && (this.listeners = {});
!this.listeners[name] && (this.listeners[name] = []);
this.listeners[name].push(listener);
return this;
},

off: function(name, listener){
if ( this.listeners && this.listeners[name] ) {
for ( var a=this.listeners[name], i=a.length-1; i>=0; i-- ) {
if ( a[i] === listener ) {
this.listeners[name].splice(i, 1);
}
}
}
return this;
},

trigger: function(name, data, context){
if ( this.listeners && this.listeners[name] ) {
for ( var i=0, a=this.listeners[name], l=a.length; i<l; i++ ) {
if ( a[i] && a[i].call ) {
a[i].call( context || this, data );
}
}
}
return this;
},

bind: function(method, args, context){
!context && args && !args.length && (context = args);
!context && (context = this);
args && (args = Array.prototype.slice.call(args));
return function(){
return (args
? method.apply(context, args.concat(Array.prototype.slice.call(arguments)))
: method.apply(context, arguments)
);
};
},

fail: function(listener){ return this.on('fail', listener); },
done: function(listener){ return this.on('done', listener); },

timeout: function(){
clearInterval(this.iid);
this.failed();
},

polling: function(){
var obj, text, ex;
if ( this.config.type === 'iframe' ) {
try { text = ((obj=this.loader.contentWindow) && obj.document.documentElement.textContent) ||
((obj=this.loader.contentWindow) && obj.document.documentElement.innerText) ||
((obj=this.loader.contentDocument) && obj.documentElement.textContent) ||
((obj=this.loader.contentDocument) && obj.documentElement.innerText);
} catch (ex) {}
}
else {
text = this.loader.textContent ||
this.loader.text ||
this.loader.innerHTML ||
this.shared.loaded && this.shared.loaded[this.config.path]
;
}
if ( text && text.split ) {
this.loaded(text);
clearInterval(this.tid);
clearInterval(this.iid);
}
},

injected: function(script, content){
var text = String(content && content.toString()),
p1 = text.indexOf('/*')+2,
p2 = text.lastIndexOf('*/')
;
!this.shared.loaded && (this.shared.loaded={});
this.shared.loaded[script] = text.substring(p1, p2);
},

load: function(config){
return config && config.split
? tf.create({ path: config })
: tf.create(config)
;
}

};

return tf;

})();

How to read a text file containing html without using input type file in JavaScript?

Question is pretty vague, so I'll just list some options to look into:

1) Firstly, if this is a browser page, you can serve the html page on the server and request it from the client.

2) Alternatively, you can have a build step that replaces some variable value with the HTML file's contents. This will avoid the HTTP request of solution (1).

3) On the other hand, if this is a node (or electron) app, in addition to solution (2), you can use node's fs to access the HTML file.

4) Lastly, perhaps the simplest but least salable solution, put the HTML in a JS object. Unlike JSON, JS objects can support new lines; e.g.

let x = {
str: `line 1
line 2`
};

Though even if you want to use a JSON file, you could include escaped new liens \n in strings.



Related Topics



Leave a reply



Submit