Can't get AJAX to work! I have a marquee on a website, got it working! But I want it to find the text of the marquee in a text file, and I want it to read the text in the text file (which is one line) and assign it to the variable called content, which is a global variable in the script tag.
When I run the website (local IIS), the marquee text is: "undefined" (without the quotes).
Why isn't it assigning the text to the variable content?
var content
function loadXMLDoc()
{
var textfile;
if (window.XMLHttpRequest)
{
textfile = new XMLHttpRequest();
}
textfile.onreadystatechange = function ()
{
if (textfile.readyState == 4 && textfile.status == 200)
{
content = textfile.responseText;
}
}
textfile.open("GET", "C:\Users\Fares\Dropbox\Sync\College\Computing\DeltaOne\MarqueeText.txt", true);
textfile.send();
}
EDIT: A million thanks to #kuncajs, as he pointed out I forgot to call the function! :) Fixed! Thanks to everyone else!
Do not use local paths like:
C:\Users\Fares\Dropbox\Sync\College\Computing\DeltaOne\MarqueeText.txt
Place it in the www directory of your IIS and state the path like:
localhost/text.txt
The server can have restricted access to your filesystem and also you should try relative paths like text.txt or absolute paths /text.txt so the paths work even when you deploy it in the production environment.
EDIT:
So if this did not help then make sure that you really call the loadXMLDoc() function. Also check that everything you do is after the AJAX ends! I mean you do the assignment in the if - when AJAX is done but you should also initialize your marquee !AFTER! the text is loaded. If you do it before it will be undefined
Try using a relative or absolute path first.
If that doesn't work check that when using your browser you can access the file (let's say your website is on mysite.com/index.html, try opening mysite.com/text.txt)
If you can't access it using your browser then you will have to configure your server to allow this file to be read, never tried IIS so I can't help you there.
Also since you are asking your XHR to be asynchronous it might take a little time before the variable is populated (depending on your/your server's speed)
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 let users on my VanillaForums forum choose whether or not to use the https protocol and I want to test if I can change image sources on the client's side using jQuery.
I want this code to change the protocol in the image source links to // instead of http:// and load before the images have loaded, so I used .ready():
$(document).ready(function () {
if (window.location.protocol == "https:") {
var $imgs = $("img");
$imgs.each(function () {
var img_src = $(this).prop("src");
if (img_src.indexOf("http://") < 0) return;
var new_img_src = img_src.replace("http:", "");
$(this).prop("src", new_img_src);
});
}
});
While it does work in changing the image sources, the URL bar still shows this:
And the console gives a warning that http://someimageurl... is not secure.
Do I need to move the code to the top of the page or will that not make a difference?
It needs to be done server side for the browser not to throw an insecure connection warning. The file with the responsible code is /library/core/functions.render.php, which you can see here.
$PhotoURL is the variable that needs to be changed. Using the following makes sure all images are loaded over the https: protocol: str_replace('http://', 'https://', $PhotoURL).
I usually don't mind global scope on smaller software but in something as big as Vanilla it's like finding a needle in a haystack.
I couldn't find any other fixes for Vanilla in particular so I hope this helps people.
I'd like to inject a couple of local .js files into a webpage. I just mean client side, as in within my browser, I don't need anybody else accessing the page to be able to see it. I just need to take a .js file, and then make it so it's as if that file had been included in the page's html via a <script> tag all along.
It's okay if it takes a second after the page has loaded for the stuff in the local files to be available.
It's okay if I have to be at the computer to do this "by hand" with a console or something.
I've been trying to do this for two days, I've tried Greasemonkey, I've tried manually loading files using a JavaScript console. It amazes me that there isn't (apparently) an established way to do this, it seems like such a simple thing to want to do. I guess simple isn't the same thing as common, though.
If it helps, the reason why I want to do this is to run a chatbot on a JS-based chat client. Some of the bot's code is mixed into the pre-existing chat code -- for that, I have Fiddler intercepting requests to .../chat.js and replacing it with a local file. But I have two .js files which are "independant" of anything on the page itself. There aren't any .js files requested by the page that I can substitute them for, so I can't use Fiddler.
Since your already using a fiddler script, you can do something like this in the OnBeforeResponse(oSession: Session) function
if ( oSession.oResponse.headers.ExistsAndContains("Content-Type", "html") &&
oSession.hostname.Contains("MY.TargetSite.com") ) {
oSession.oResponse.headers.Add("DEBUG1_WE_EDITED_THIS", "HERE");
// Remove any compression or chunking
oSession.utilDecodeResponse();
var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);
// Find the end of the HEAD script, so you can inject script block there.
var oRegEx = oRegEx = /(<\/head>)/gi
// replace the head-close tag with new-script + head-close
oBody = oBody.replace(oRegEx, "<script type='text/javascript'>console.log('We injected it');</script></head>");
// Set the response body to the changed body string
oSession.utilSetResponseBody(oBody);
}
Working example for www.html5rocks.com :
if ( oSession.oResponse.headers.ExistsAndContains("Content-Type", "html") &&
oSession.hostname.Contains("html5rocks") ) { //goto html5rocks.com
oSession.oResponse.headers.Add("DEBUG1_WE_EDITED_THIS", "HERE");
oSession.utilDecodeResponse();
var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);
var oRegEx = oRegEx = /(<\/head>)/gi
oBody = oBody.replace(oRegEx, "<script type='text/javascript'>alert('We injected it')</script></head>");
oSession.utilSetResponseBody(oBody);
}
Note, you have to turn streaming off in fiddler : http://www.fiddler2.com/fiddler/help/streaming.asp and I assume you would need to decode HTTPS : http://www.fiddler2.com/fiddler/help/httpsdecryption.asp
I have been using fiddler script less and less, in favor of fiddler .Net Extensions - http://fiddler2.com/fiddler/dev/IFiddlerExtension.asp
If you are using Chrome then check out dotjs.
It will do exactly what you want!
How about just using jquery's jQuery.getScript() method?
http://api.jquery.com/jQuery.getScript/
save the normal html pages to the file system, add the js files manually by hand, and then use fiddler to intercept those calls so you get your version of the html file
Let's say I have a web page (/index.html) that contains the following
<li>
<div>item1</div>
details
</li>
and I would like to have some javascript on /index.html to load that
/details/item1.html page and extract some information from that page.
The page /details/item1.html might contain things like
<div id="some_id">
picture
map
</div>
My task is to write a greasemonkey script, so changing anything serverside is not an option.
To summarize, javascript is running on /index.html and I would
like to have the javascript code to add some information on /index.html
extracted from both /index.html and /details/item1.html.
My question is how to fetch information from /details/item1.html.
I currently have written code to extract the link (e.g. /details/item1.html)
and pass this on to a method that should extract the wanted information (at first
just .innerHTML from the some_id div is ok, I can process futher later).
The following is my current attempt, but it does not work. Any suggestions?
function get_information(link)
{
var obj = document.createElement('object');
obj.data = link;
document.getElementsByTagName('body')[0].appendChild(obj)
var some_id = document.getElementById('some_id');
if (! some_id) {
alert("some_id == NULL");
return "";
}
return some_id.innerHTML;
}
First:
function get_information(link, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", link, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
callback(xhr.responseText);
}
};
xhr.send(null);
}
then
get_information("/details/item1.html", function(text) {
var div = document.createElement("div");
div.innerHTML = text;
// Do something with the div here, like inserting it into the page
});
I have not tested any of this - off the top of my head. YMMV
As only one page exists in the client (browser) at a time and all other (virtual/possible) pages are on the server, how will you get information from another page using JavaScript as you will have to interact with the server at some point to retrieve the second page?
If you can, integrate some AJAX-request to load the second page (and parse it), but if that's not an option, I'd say you'll have to load all pages that you want to extract information from at the same time, hide the bits you don't want to show (in hidden DIVs?) and then get your index (or whoever controls the view) to retrieve the needed information from there ... even though that sounds pretty creepy ;)
You can load the page in a hidden iframe and use normal DOM manipulation to extract the results, or get the text of the page via AJAX, grab the part between <body...>...</body>¨ and temporarily inject it into a div. (The second might fail for some exotic elements like ins.) I would expect Greasemonkey to have more powerful functions than normal Javascript for stuff like that, though - it might be worth to thumb through the documentation.
Question:
IE and Firefox / Safari seem to deal differently with BASE HREF and Javascript window.location type requests. First, is this an accurate description of the problem? What's going on? And what's the best cross-browser solution to deal with this situation?
Context:
I have a small PHP flat file sitelet (it's actually a usability testing prototype).
I dynamically generate the BASE tag's HREF value in PHP, i.e. if it's running on our company's server, it's:
$basehref = 'http://www.example.com/alpha/bravo/UsabilityTest/';
and on my local dev machine, it's:
$basehref = 'http://ellen.local/delta/echo/foxtrot/UsabilityTest/';
For one of the tasks, I collect some user input, do some transformations on it in Javascript, and send to the server using code like this:
function allDone() {
// elided code for simplicity of stackoverflow question
var URI = "ProcessUserInput.php?";
URI = URI + "alphakeys=" + encodeURI( keys.join(",") );
URI = URI + "&sortedvalues=" + encodeURI( values.join(",") );
window.location = URI;
}
Both the javascript file (containing function allDone()) and the processing PHP script (ProcessUserInput.php) live in a subdirectory of UsabilityTest. In other words, their actual URL is
http://www.example.com/alpha/bravo/UsabilityTest/foxtrot/ProcessUserInput.php
aka
$basehref . '/foxtrot/ProcessUserInput.php'
The Problem
IE's JavaScript basically seems to ignore the BASE HREF. The javascript and the PHP processor live in the same directory, so the call to ProcessUserInput.php works out fine. The input gets processed and everything works fine.
But when I test on Firefox, the JavaScript does appear to use the BASE HREF, because the script's output gets sent to
$basehref . '/ProcessUserInput.php'
This breaks, because ProcessUserInput.php is in a subdirectory of basehref. However, if I add the subdirectory name to the javascript, it no longer works in IE.
Solutions?
I can think of a few ways to solve this:
In Javascript, read the HREF property of the BASE tag and manually prepend to var URI in the javascript, calling a fully-resolved absolute URL
Process the .js file with PHP and insert the $basehref variable into the script
Move the files around
Something else?
I'm sure there must be other ways to solve this too. What's the best way to deal with BASE HREF in JavaScript when IE and Firefox apply it differently in JavaScript?
Using the assign method of window.location seems like the most straightforward answer.
Instead of
window.location = URI;
I'm using this:
window.location.assign( URI );
which is doing the right thing in both IE and Firefox.
IE and Firefox / Safari seem to deal differently with BASE HREF and Javascript window.location type requests.
Yes, this is a long-standing difference going back to the early days of Netscape-vs-IE.
IE enforces base-href only at the point a document element is interacted-with. So, you can createElement('a'), set a relative href and click() it*, but the base-href will be ignored; appendChild it to the document containing the base-href, and it'll work.
On the other browsers the base-href is taken as global per-window and always applied. Which is right? It seems to be unspecified. The original JavaScript docs say only that location.hash (and hence, location applied as a string):
represents a complete URL
So setting it to a relative URL would seem to be an undefined operation.
(*: link.click() is a non-standard method supported by IE and Opera)
read the HREF property of the BASE tag and manually prepend
Probably what I'd do, yeah, if you're dead set on using <base>.
I believe you want to modify window.location.pathname, not window.location. window.location is a Location object, that has multiple variables. As a result, the effects of changing it is not well defined. However, window.location.pathname is defined as the path relative to the host, which is what you want.
If you want to read up more on the many variables you can change in window.location, I'd check here. According to Mozilla's documentation, changing any variable in window.location should reload the page with a new URL corresponding to those changes.
I had the same problem today, after some researching, couldn´t findn any way to override this issue in IE9, what is a requiremente for my project, so, i did the following approach (jquery based, but it´s really easy to make it in simple javascript).
href = function(url){
if ($("base").length > 0 ){
location.href= $("base").attr("href")+url;
}else{
location.href = url;
}
}
And then, change
location.href= 'emp/start'
to
href('emp/start');
just add $('base').attr('href') before the link. (using jquery) or
document.getElementBytagname('base').href
You can always use Vanilla JS :)
var href = document.getElementBytagname('base')[0].href
I hope this helps.