XHR loading resources from separate directory - javascript

I have a simple XHR to load 'testdirectory/testpage.html'
var xhr; (XMLHttpRequest) ? xhr= new XMLHttpRequest() : xhr= new ActiveXObject("Microsoft.XMLHTTP");
xhr.onload = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
var preview = xhr.responseText;
document.getElementById("content").innerHTML = preview;
}
}
xhr.open("GET", "testdirectory/testpage.html", true);
xhr.send();
I have it set up to display on button click. Works great.
Let's say testpage.html looks like this:
<h1>Loaded Page Heading!</h1>
<img src="main.png">
It will load but the image that is displaying is not main.png from that directory, it is main.png from the directory of the page that placed the XHR.
Is there a way to get the returned HTML to point to the 'testdirectory/main.png' image and not just use the current directory from the XHR? I'm looking for an alternative to changing the HTML of the page retrieved since that would defeat the purpose of what I'm trying to do.
I've been searching through StackOverflow for about 20 minutes, and I've googled a couple of different things. It seems like a question that must have been asked sometime before but is difficult to phrase/find.

I'm afraid you won't be able to achieve what you want without changing the retrieved HTML.
The xhr.responseText you receive from the XHR request is a string of HTML. When you do:
document.getElementById("content").innerHTML = preview;
you're taking that string of HTML and assigning it to the innerHTML property of that element. The innerHTML property parses that string of HTML and assigns the resulting nodes as children of the element. Any URLs in that parsed HTML will use the current document's base URL.
So basically, all you did was take some HTML string, parse it and append it to the current document. The innerHTML property doesn't care or know from where you obtained that HTML. The resulting nodes will behave exactly as any other HTML in the rest of the document.
It seems to me you're expecting the behavior of an iframe. But that's a totally different beast, and works differently to what you're doing here. An iframe is basically an embedded document, with it's own DocumentObjectModel (DOM) and, therefore, it's own base URL property.
In case you decide it's acceptable to modify the HTML string, you could do something like this:
var preview = xhr.responseText.replace('src="', 'src="testdirectory/');
Have in mind though that you would need to do the same for URLs in other types of attributes, such as href.

Related

Javascript read and display content of a file

I want to read a file that's saved in the same folder. Then I want to show its content in a div in index.html. The problem: when I used require("fs") it didn't work since it wasn't running server-side. I have been looking around and can't find a simple answer. I want to make my website a little dynamic, so here is the code that should fire upon a button click:
function videos() {
var body = *read a file("insertfilename")*;
console.log(body);
document.getElementById("body").innerHTML = body;
}
"body" in this case is just the id I gave the div.
!EDIT!
Now to explain it further. I want to use it as my main website. When I go onto there it should open an empty html file, which has a scriptfile as source. "onload" it should read a file , which is also already on the server, and put its content into a div inside of the body. If I click on a hotlink or a Button, it should read another file and put that content into that div instead. Maybe that gives a little clarification on what I am trying to do. I dont want to reload to open other sites of mine.
Seems like you need some basic file fetching since you are not using a server. Have you tried FileReader for javascript? It is a very simple and straightforward object. The example on the page seems similar to what you are trying to accomplish, except you want to fetch the file, not the user.
You can use AJAX. It stands for Asynchronous JavaScript And XML. You can send asynchronous requests to server with it. Just make sure that file that you are requesting is on the same domain as JS file.
function videos() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() { //this will execute when you receive response from the server
if (this.readyState == 4 && this.status == 200) {
document.getElementById("body").innerHTML = this.responseText;
console.log(this.responseText)
}
};
xhttp.open("GET", "filename.txt", true);
xhttp.send();
}
Here is W3schools tutorial if you want to learn more.

Request plain text file in javascript from URL?

I started a blog recently and coded it by hand. It is a static, CSS/HTML5 website. Upon sharing it with friends, I realized that when I would update it via FTP, it would be cached already by their browsers. I decided that I would keep all of my blog posts on new pages and then create a landing page that would somehow determine the newest post and forward users there after they clicked an enter button or something like that.
I was able to create a button that could forward them to a specific link, but I want to create a script that will always forward them to the newest page. So I created a file called 'getLatest.json' and uploaded it to an 'api' subfolder of my site. I then tried to use an XMLHttpRequest to load it:
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
window.location = "http://latestBlogPost.com" +
xhttp.responseText.today;
//Today is a parent in the object returned.
}
};
xhttp.open("POST", "http://myWebsite.com/api/getLatest.json", true);
xhttp.send();
}
But that didn't work. The response was a null string. I tried using jquery to no avail.
I tried uploading a file called getLatest.html which contained the url in plaintext. That didn't work either.
tl;dr: Is there some way that I can get plaintext from a URL's html content?
edit: getLatest.json and getLatest.html contain a link to the newest blog post.
There are couple of ways to do this.
First your code is not working because you are using a "POST" it should be "GET", if you do that it will work.
Second easiest way is to create a java script file with variable declared and reference that file to your website
<script type="text/javascript" src="http://your javascript file"> </script>
This file contains your variable like this
var latestBlog = "http://....";
in your code use this variable. No more code required. but as i mentioned earlier if you change your HTTP Verb to get your code will work

Get script content [duplicate]

If I have a script tag like this:
<script
id = "myscript"
src = "http://www.example.com/script.js"
type = "text/javascript">
</script>
I would like to get the content of the "script.js" file. I'm thinking about something like document.getElementById("myscript").text but it doesn't work in this case.
tl;dr script tags are not subject to CORS and same-origin-policy and therefore javascript/DOM cannot offer access to the text content of the resource loaded via a <script> tag, or it would break same-origin-policy.
long version:
Most of the other answers (and the accepted answer) indicate correctly that the "correct" way to get the text content of a javascript file inserted via a <script> loaded into the page, is using an XMLHttpRequest to perform another seperate additional request for the resource indicated in the scripts src property, something which the short javascript code below will demonstrate. I however found that the other answers did not address the point why to get the javascript files text content, which is that allowing to access content of the file included via the <script src=[url]></script> would break the CORS policies, e.g. modern browsers prevent the XHR of resources that do not provide the Access-Control-Allow-Origin header, hence browsers do not allow any other way than those subject to CORS, to get the content.
With the following code (as mentioned in the other questions "use XHR/AJAX") it is possible to do another request for all not inline script tags in the document.
function printScriptTextContent(script)
{
var xhr = new XMLHttpRequest();
xhr.open("GET",script.src)
xhr.onreadystatechange = function () {
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log("the script text content is",xhr.responseText);
}
};
xhr.send();
}
Array.prototype.slice.call(document.querySelectorAll("script[src]")).forEach(printScriptTextContent);
and so I will not repeat that, but instead would like to add via this answer upon the aspect why itthat
Do you want to get the contents of the file http://www.example.com/script.js? If so, you could turn to AJAX methods to fetch its content, assuming it resides on the same server as the page itself.
Update: HTML Imports are now deprecated (alternatives).
---
I know it's a little late but some browsers support the tag LINK rel="import" property.
http://www.html5rocks.com/en/tutorials/webcomponents/imports/
<link rel="import" href="/path/to/imports/stuff.html">
For the rest, ajax is still the preferred way.
I don't think the contents will be available via the DOM. You could get the value of the src attribute and use AJAX to request the file from the server.
yes, Ajax is the way to do it, as in accepted answer. If you get down to the details, there are many pitfalls. If you use jQuery.load(...), the wrong content type is assumed (html instead of application/javascript), which can mess things up by putting unwanted <br> into your (scriptNode).innerText, and things like that. Then, if you use jQuery.getScript(...), the downloaded script is immediately executed, which might not be what you want (might screw up the order in which you want to load the files, in case you have several of those.)
I found it best to use jQuery.ajax with dataType: "text"
I used this Ajax technique in a project with a frameset, where the frameset and/or several frames need the same JavaScript, in order to avoid having the server send that JavaScript multiple times.
Here is code, tested and working:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
<script id="scriptData">
var scriptData = [
{ name: "foo" , url: "path/to/foo" },
{ name: "bar" , url: "path/to/bar" }
];
</script>
<script id="scriptLoader">
var LOADER = {
loadedCount: 0,
toBeLoadedCount: 0,
load_jQuery: function (){
var jqNode = document.createElement("script");
jqNode.setAttribute("src", "/path/to/jquery");
jqNode.setAttribute("onload", "LOADER.loadScripts();");
jqNode.setAttribute("id", "jquery");
document.head.appendChild(jqNode);
},
loadScripts: function (){
var scriptDataLookup = this.scriptDataLookup = {};
var scriptNodes = this.scriptNodes = {};
var scriptNodesArr = this.scriptNodesArr = [];
for (var j=0; j<scriptData.length; j++){
var theEntry = scriptData[j];
scriptDataLookup[theEntry.name] = theEntry;
}
//console.log(JSON.stringify(scriptDataLookup, null, 4));
for (var i=0; i<scriptData.length; i++){
var entry = scriptData[i];
var name = entry.name;
var theURL = entry.url;
this.toBeLoadedCount++;
var node = document.createElement("script");
node.setAttribute("id", name);
scriptNodes[name] = node;
scriptNodesArr.push(node);
jQuery.ajax({
method : "GET",
url : theURL,
dataType : "text"
}).done(this.makeHandler(name, node)).fail(this.makeFailHandler(name, node));
}
},
makeFailHandler: function(name, node){
var THIS = this;
return function(xhr, errorName, errorMessage){
console.log(name, "FAIL");
console.log(xhr);
console.log(errorName);
console.log(errorMessage);
debugger;
}
},
makeHandler: function(name, node){
var THIS = this;
return function (fileContents, status, xhr){
THIS.loadedCount++;
//console.log("loaded", name, "content length", fileContents.length, "status", status);
//console.log("loaded:", THIS.loadedCount, "/", THIS.toBeLoadedCount);
THIS.scriptDataLookup[name].fileContents = fileContents;
if (THIS.loadedCount >= THIS.toBeLoadedCount){
THIS.allScriptsLoaded();
}
}
},
allScriptsLoaded: function(){
for (var i=0; i<this.scriptNodesArr.length; i++){
var scriptNode = this.scriptNodesArr[i];
var name = scriptNode.id;
var data = this.scriptDataLookup[name];
var fileContents = data.fileContents;
var textNode = document.createTextNode(fileContents);
scriptNode.appendChild(textNode);
document.head.appendChild(scriptNode); // execution is here
//console.log(scriptNode);
}
// call code to make the frames here
}
};
</script>
</head>
<frameset rows="200pixels,*" onload="LOADER.load_jQuery();">
<frame src="about:blank"></frame>
<frame src="about:blank"></frame>
</frameset>
</html>
related question
.text did get you contents of the tag, it's just that you have nothing between your open tag and your end tag. You can get the src attribute of the element using .src, and then if you want to get the javascript file you would follow the link and make an ajax request for it.
In a comment to my previous answer:
I want to store the content of the script so that I can cache it and use it directly some time later without having to fetch it from the external web server (not on the same server as the page)
In that case you're better off using a server side script to fetch and cache the script file. Depending on your server setup you could just wget the file (periodically via cron if you expect it to change) or do something similar with a small script inthe language of your choice.
if you want the contents of the src attribute, you would have to do an ajax request and look at the responsetext. If you where to have the js between and you could access it through innerHTML.
This might be of interest: http://ejohn.org/blog/degrading-script-tags/
I had a same issue, so i solve it this way:
The js file contains something like
window.someVarForReturn = `content for return`
On html
<script src="file.js"></script>
<script>console.log(someVarForReturn)</script>
In my case the content was html template. So i did something like this:
On js file
window.someVarForReturn = `<did>My template</div>`
On html
<script src="file.js"></script>
<script>
new DOMParser().parseFromString(someVarForReturn, 'text/html').body.children[0]
</script>
You cannot directly get what browser loaded as the content of your specific script tag (security hazard);
But
you can request the same resource (src) again ( which will succeed immediately due to cache ) and read it's text:
const scriptSrc = document.querySelector('script#yours').src;
// re-request the same location
const scriptContent = await fetch(scriptSrc).then((res) => res.text());
If you're looking to access the attributes of the <script> tag rather than the contents of script.js, then XPath may well be what you're after.
It will allow you to get each of the script attributes.
If it's the example.js file contents you're after, then you can fire off an AJAX request to fetch it.
It's funny but we can't, we have to fetch them again over the internet.
Likely the browser will read his cache, but a ping is still sent to verify the content-length.
[...document.scripts].forEach((script) => {
fetch(script.src)
.then((response) => response.text() )
.then((source) => console.log(source) )
})
Using 2008-style DOM-binding it would rather be:
document.getElementById('myscript').getAttribute("src");
document.getElementById('myscript').getAttribute("type");
You want to use the innerHTML property to get the contents of the script tag:
document.getElementById("myscript").innerHTML
But as #olle said in another answer you probably want to have a read of:
http://ejohn.org/blog/degrading-script-tags/
If a src attribute is provided, user agents are required to ignore the content of the element, if you need to access it from the external script, then you are probably doing something wrong.
Update: I see you've added a comment to the effect that you want to cache the script and use it later. To what end? Assuming your HTTP is cache friendly, then your caching needs are likely taken care of by the browser already.
I'd suggest the answer to this question is using the "innerHTML" property of the DOM element. Certainly, if the script has loaded, you do not need to make an Ajax call to get it.
So Sugendran should be correct (not sure why he was voted down without explanation).
var scriptContent = document.getElementById("myscript").innerHTML;
The innerHTML property of the script element should give you the scripts content as a string provided the script element is:
an inline script, or
that the script has loaded (if using the src attribute)
olle also gives the answer, but I think it got 'muddled' by his suggesting it needs to be loaded through ajax first, and i think he meant "inline" instead of between.
if you where to have the js between and you could access it through innerHTML.
Regarding the usefulness of this technique:
I've looked to use this technique for client side error logging (of javascript exceptions) after getting "undefined variables" which aren't contained within my own scripts (such as badly injected scripts from toolbars or extensions) - so I don't think it's such a way out idea.
Not sure why you would need to do this?
Another way round would be to hold the script in a hidden element somewhere and use Eval to run it. You could then query the objects innerHtml property.

Using JavaScript (only - no libraries) to load another page into div

What is the JavaScript equivalent of $('content').load('page.html'); I am trying to load content in another page into my div but I cannot find a method for plain old JavaScript.
The good old JavaScript:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
var myRequest = new XMLHttpRequest(); //XMLHttpRequest is how you do it
myRequest.onreadystatechange = function(e){
if(myRequest.readyState == 4 && myRequest.status == 200){
var data = myRequest.responseText; //returned data
document.querySelector("div").innerHTML = data; //not safe but whatever
}
};
myRequest.open("get", "url here", true);
myRequest.send();
It is always better to do it with plain JavaScript first before using those fancy jQuery one-method-takes-care-of-everything-for-you methods.
Your question has two parts:
Grabbing some content on a server from the client
Pushing that content into a div.
For part one, see this thread for instructions on using XMLHTTPRequest():
HTTP GET request in JavaScript?
For part two, as for populating the div, it's this simple:
document.getElementById('content').innerHTML = 'someContent';
Note that you may want to scrub your content before populating the div depending on the source of the page you are requesting, as using JS to populate a div with raw HTML is an attack vector that hackers might try to exploit.
Have you tried taking a look at using iframes? http://www.w3schools.com/tags/tag_iframe.asp
It's called an XML HTTP Request (XHR). See the docs here.
As you can see from the source code here, jQuery's load() function calls the ajax() function to load the external html.
Under the hood, the ajax() function uses XMLHttpRequest which is how you would retrieve the file using vanilla JavaScript.

SharePoint Designer - xmlHTTPRequest innerHTML

I have a sharepoint page that filters a data view from a query string in the address bar. I wanted to add further functionality by also returning back any of the files in the main sharepoint library that matches the query string in the address bar. I added a content editor webpart and I added a xmlHTTPRequest that imports the search page with the filtered results into the webpart div. If I use innerHTML = xmlhttp.responseText to populate the webpart div I receive an error message but when I change it to innerText I receive the text from the website. The error message I received was "Unkown runtime error".
var url = "searchresults.aspx?k=*.xlsx&v1=date&start1=1"
xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET',url,false);
xmlhttp.onreadystatechange = function()
{
if(xmlhttp.readyState == 4);
{
document.getElementById("dv_content").innerHTML = xmlhttp.responseText
}
}
xmlhttp.send(null);
Thanks,
Anthony
Before going into the code, is the javascript running on the same virtual path as the searchresults.aspx file? Try putting the entire path first, like http://server/_layouts/searchresults.aspx?etc..
If I remember right, Unknown runtime error in IE is the rendering engine getting cranky about what you're trying to put into the element.
Here's some discussion on the subject.
I believe you'll need to massage the HTML you're trying to insert to something that IE is less surly about. You can do that either before or after you curse that browser's name.

Categories

Resources