XMLHttpRequest.send failing with relative path - javascript

I'm having difficulty with something probably remedial. I'm developing a website without a server. In doing so, I run into problems when trying to access files via XMLHttpRequest.
As you can see in the example code snippet, I create the variable, open it with a relative path to the desired file, and use the send function.
When I use a relative path that has to traverse up to a parent directory, the send() function fails. However, if I provide a path that is either in the same directory as the webpage or forward in a subfolder of the current webpage directory, i see that the XMLHttpRequest returns successfully. In these successful cases, I can see the data of the test file in request.responseText.
Any help with this would be greatly appreciated.
The only lead I have right now is that there may be a security threat that prevents 'get' requests that traverse up the parent directory.
Thank you.
Code Snippet:
function test(){
var request = new XMLHttpRequest();
request.open('GET', "../test.txt", true);
request.send();//FAILS HERE
//Get Response
var response = request.responseText;
}
function test2(){
var request = new XMLHttpRequest();
request.open('GET', "test.txt", true);
request.send();
//Get Response
var response = request.responseText; //SUCCESSFUL
}

From the MDN website, about the Gecko engine and therefore the Firefox browser:
a file can read another file only if the parent directory of the originating file is an ancestor directory of the target file.
Similar rules exist in other browsers. This is a limitation of the file:/// protocol. It's there for a very good reason. There's no point trying to break it. The solution is to run a local server on your computer, which isn't even slightly difficult.
To clarify: let's presume that you have a file structure like this:
- file1.html
- dir1/
- file2.html
- dir2/
- index.html
- file3.html
- dir3/
- file4.html
From within index.html, you can use Javascript to access file3.html and file4.html. It cannot access file1.html or file2.html.

Open the file in your browser directly using file->open then copy the URL in the address bar.

Related

XMLHttpRequest is not defined

I have a server using node and express. I'm building the client app. It's supposed to get data from the server like so:
let req = new XMLHTTPRequest();
req.open('GET', 'localhost:5000/newarticle');
req.onload = function() {
let data = JSON.parse(req.responseText);
renderHTML(data);
}
req.send();
This code is part of a main.js file which is linked to my index.html file. The index.html file is served by express to the client when they access the website. On index.html, there's a button, with functionality associated with the onclick event that's defined in main.js. So far, so good. But when the button is clicked, I get a console message in the browser reading "XMLHttpRequest is not defined."
My understanding is that the browser (Chrome/V8) and node are separate JavaScript environments. Things like XMlHttpRequest, which are defined in node, are not defined in V8.
This is confusing to me. No tutorial I find on how to use AJAX mentions this as an issue. I haven't been able to find a source that digs into how I can serve up an HTML + javascript page that allows the user to send AJAX requests back to the server that addresses this issue. Honestly, I don't even know quite what to search for to try and find an explanation for this set of issues. Any advice or links would be very appreciated!

How do I detect with JavaScript or JQuery whether a URL points to a web page or a binary file?

I'm crawling a web page list of links that are either web pages or large binary files (PPT etc), using javascript and jquery.
How do I detect whether the content is a web page ('text/html') or not? I'm pretty sure it is looking at the HTTP header using $.ajax, and I know there are some similar posted questions, but I can't find an example that fits this particular question.
You can check extension of url - lightest method.
Or you can try ajax solution
var url = 'someurl';
var xhttp = new XMLHttpRequest();
xhttp.open('HEAD', url);
xhttp.onreadystatechange = function () {
if (this.readyState == this.DONE) {
console.log(this.status);
console.log(this.getResponseHeader("Content-Type"));
}
};
xhttp.send();
You won't reliably be able to infer the type from the URL, as it may contain an extension like exe or html, but doesn't have to, and if it does, it's not a guarantee.
The closest you can get without completely downloading and examining the file is probably to fire off a HEAD HTTP request to the URL. This should return the response headers without the body, which in turn should contain the Content-Type header. This all depends on the implementation and configuration of the backend though, so no guarantee that the request will be answered correctly or even answered at all.
If you have the file names, you can use
filename.split('.').pop()
This returns the extension of the file.

read from a local text file and update and updating the content in an html tag

I need to read a local text file and update my html page with the contents of the text file.
I do not have so much browser support as I work on an embedded system.
But it gave the following error :
XMLHttpRequest cannot load file:///C:/Documents%20and%20Settings/aryas/Desktop/localtoken.txt. Cross origin requests are only supported for HTTP.
The code is as follows.
<script>
window.onload = function readTextFile()
{
console.log("Inside function");
var file = "localtoken.txt";
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, true);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var allText = rawFile.responseText;
document.getElementById("token").innerHTML = allText;
}
}
}
rawFile.send(null);
}
</script>
Put this text file at the same directory as your index.html.
In an ajax request you path will look like it's on you website - 'readfile.txt'
You need to pass file URL into XMLHttpRequest.
xmlhttp.open('GET', 'http://localhost/file.txt', false);
For this you need to configure a webserver which can process your request. For instance you can install Apache server and bring it up and deploy file.txt into it. Once the browser sends request to webserver for file.txt the webserver returns you the file and the response you can process with the same approach what you have mentioned in the question.
Short answer:
You cannot do what you want, as you are doing it right now. You have to serve the files in a web server. Try LightHTTPD, Nginx or Mongoose
Long answer:
From the error you're getting, you must be opening the index.html file (the file with the script) without serving it from a web server (to confirm this, let me ask: does the URL in the browser start with file://?).
As the class name states, XMLHttpRequest only supports HTTP/HTTPS requests (blob URIs are in development, as stated here: http://en.wikipedia.org/wiki/XMLHttpRequest).
As in matter of fact, you will not be able to load/save files from your file system without the user to manually choose the file(s), as this is a security threat (imagine you open a website and it loads your C: and sends it to the server, do you want a website to do it?).
For loading your localtoken.txt file, serve the files in a light and small webserver (as you are working on an embedded system). The ones I suggested in the short answer fill these requirements, but from this SO question it seems that Mongoose is the way to go.

Go to local URL with Javascript

Same question as here but I need to go to local URL's in Firefox
I tried with code like
var url = "file:///E:/Test/Test.htm";
window.location.href = url;
but id didn't work. Tried to go with window.location = url; and also tried with url = "file://E:/Test/Test.htm"; (double "/" instead of triple "/") and still doesn't work.
Thanks
When I try this:
window.location.href = "file:///C:/Users/Cerbrus/Documents/SomeFile.js"
(Yes, it is a valid path.)
Chrome throws me this error:
Not allowed to load local resource: file:///C:/Users//Documents/File.js
This is because JavaScript does not have access to local files (due to it being sandboxed), and you're setting the new url with JavaScript.
"SandBoxed" means a technology has restricted (or no) access outside a certain set of bounds. In the case of browsers, this means that the code that runs on the page can not access files on your system (Otherwise, it would be easy to "steal" data, by just having a look at the user's file system).
However,
Say, I have 2 files:
C:/Test/Test.htm
C:/Test/Test1.htm
Test.htm contains only this:
<script>
window.location = "file:///C:/Test/Test1.htm";
</script>
This will actually redirect to Test1.htm, since the target file is on the same domain as where the source file's from.
I guess its not allowed to load local resource from javascript
Unless you have a local http server running:
var url = "http://localhost/MySite/Default.aspx";
window.location.href = url;
It will work
You cannot access the file from the local system. Since the Browser works in the sandbox mode and you cannot breach the sandbox and reach the local file system since it would violate the security. Either try to directly load using an AJAX request else what you are trying to do is not possible due to sandbox restrictions and also does not comply with the security policies.
window.location.href = window.location.pathname + (your local file name or path)
window.open(url); // here url can be anything

XMLHttpRequest cannot load file:///. Origin null is not allowed by Access-Control-Allow-Origin [duplicate]

I'm trying to create a website that can be downloaded and run locally by launching its index file.
All the files are local, no resources are used online.
When I try to use the AJAXSLT plugin for jQuery to process an XML file with an XSL template (in sub directories), I receive the following errors:
XMLHttpRequest cannot load file:///C:/path/to/XSL%20Website/data/home.xml. Origin null is not allowed by Access-Control-Allow-Origin.
XMLHttpRequest cannot load file:///C:/path/to/XSL%20Website/assets/xsl/main.xsl. Origin null is not allowed by Access-Control-Allow-Origin.
The index file making the request is file:///C:/path/to/XSL%20Website/index.html while the JavaScript files used are stored in file:///C:/path/to/XSL%20Website/assets/js/.
How can I do to fix this issue?
For instances where running a local webserver is not an option, you can allow Chrome access to file:// files via a browser switch. After some digging, I found this discussion, which mentions a browser switch in opening post. Run your Chrome instance with:
chrome.exe --allow-file-access-from-files
This may be acceptable for development environments, but little else. You certainly don't want this on all the time. This still appears to be an open issue (as of Jan 2011).
See also: Problems with jQuery getJSON using local files in Chrome
Essentially the only way to deal with this is to have a webserver running on localhost and to serve them from there.
It is insecure for a browser to allow an ajax request to access any file on your computer, therefore most browsers seem to treat "file://" requests as having no origin for the purpose of "Same Origin Policy"
Starting a webserver can be as trivial as cding into the directory the files are in and running:
python -m http.server
[Edit Thanks #alextercete, for pointing out that it has updated in Python3]
This solution will allow you to load a local script using jQuery.getScript(). This is a global setting but you can also set the crossDomain option on a per-request basis.
$.ajaxPrefilter( "json script", function( options ) {
options.crossDomain = true;
});
What about using the javascript FileReader function to open the local file, ie:
<input type="file" name="filename" id="filename">
<script>
$("#filename").change(function (e) {
if (e.target.files != undefined) {
var reader = new FileReader();
reader.onload = function (e) {
// Get all the contents in the file
var data = e.target.result;
// other stuffss................
};
reader.readAsText(e.target.files.item(0));
}
});
</script>
Now Click Choose file button and browse to the file file:///C:/path/to/XSL%20Website/data/home.xml
Here is an applescript that will launch Chrome with the --allow-file-access-from-files switch turned on, for OSX/Chrome devs out there:
set chromePath to POSIX path of "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
set switch to " --allow-file-access-from-files"
do shell script (quoted form of chromePath) & switch & " > /dev/null 2>&1 &"
Launch chrome like so to bypass this restriction: open -a "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --args --allow-file-access-from-files.
Derived from Josh Lee's comment but I needed to specify the full path to Google Chrome so as to avoid having Google Chrome opening from my Windows partition (in Parallels).
The way I just worked around this is not to use XMLHTTPRequest at all, but include the data needed in a separate javascript file instead. (In my case I needed a binary SQLite blob to use with https://github.com/kripken/sql.js/)
I created a file called base64_data.js (and used btoa() to convert the data that I needed and insert it into a <div> so I could copy it).
var base64_data = "U1FMaXRlIGZvcm1hdCAzAAQA ...<snip lots of data> AhEHwA==";
and then included the data in the html like normal javascript:
<div id="test"></div>
<script src="base64_data.js"></script>
<script>
data = atob(base64_data);
var sqldb = new SQL.Database(data);
// Database test code from the sql.js project
var test = sqldb.exec("SELECT * FROM Genre");
document.getElementById("test").textContent = JSON.stringify(test);
</script>
I imagine it would be trivial to modify this to read JSON, maybe even XML; I'll leave that as an exercise for the reader ;)
You can try putting 'Access-Control-Allow-Origin':'*' in response.writeHead(, {[here]}).
use the 'web server for chrome app'. (you actually have it on your pc, wether you know or not. just search it in cortana!). open it and click 'choose file' choose the folder with your file in it. do not actually select your file. select your files folder then click on the link(s) under the 'choose folder' button.
if it doesnt take you to the file, then add the name of the file to the urs. like this:
https://127.0.0.1:8887/fileName.txt
link to web server for chrome: click me
If you only need to access the files locally then you can include the exact path to the file, rather than using
../images/img.jpg
use
C:/Users/username/directoryToImg/img.jpg
The reason CORS is happening is because you are trying to traverse to another directory within a webpage, by including the direct path you are not changing directory, you are pulling from a direct location.

Categories