Read a text file - javascript

I have looked everywhere and surprisingly can't find a good solution to this! I've got the following code that is supposed to read a text file and display it's contents. But it's not reading, for some reason. Am I doing something wrong?
FTR, I can't use PHP for this. It's gotta be Javascript.
var txtFile = new XMLHttpRequest();
txtFile.open("GET", "http://www.mysite.com/todaysTrivia.txt", true);
txtFile.send(null);
txtFile.onreadystatechange = function() {
if (txtFile.readyState == 4) { // Makes sure the document is ready to parse.
alert(txtFile.responseText+" - "+txtFile.status);
//if (txtFile.status === 200) { // Makes sure it's found the file.
var doc = document.getElementById("Trivia-Widget");
if (doc) {
doc.innerHTML = txtFile.responseText ;
}
//}
}
txtFile.send(null);
}
Any good ideas what I'm doing wrong? It just keeps givimg me a zero status.
EDIT: I guess it would be a good idea to explain why I need this code. It's basically a widget that other folks can put on their own websites that grabs a line of text from my website and displays it on theirs. The problem is that it really can't be server-side since I've got zero control over everyone else's sites that use this.

If this is cross domain, you won't be able to do this with an xmlhttprequest due to the same origin policy.

This exmaple contains jQuery code.
var text;
$.get( "proxy.php", function(data) {
text = data.responseText;
});
Then in proxy.php:
<?php
header('Content-type: application/xml');
$daurl = 'http://www.mysite.com/todaysTrivia.txt';
$handle = fopen($daurl, "r");
if ($handle) {
while (!feof($handle)) {
$buffer = fgets($handle, 4096);
echo $buffer;
}
fclose($handle);
}
Example taken from here:
http://jquery-howto.blogspot.com/2009/04/cross-domain-ajax-querying-with-jquery.html
As explained before, xmlhttp is designed for forbid cross domain requests for security issues. But nothing prevents you from doing this on your server in PHP.
Another example can be found here: http://usejquery.com/posts/9/the-jquery-cross-domain-ajax-guide

Your problem could be with the fact that you can only request XML data from the same domain via Javascript. This is the biggest issue with AJAX calls - if the text file is on another server, you can't get it via AJAX. If it's on the same server, make your request using a relative URL (no http://).
EDIT
Now that I know what you're trying to accomplish ... my recommendation would be to use an iFrame. Build the system on your server using server-side code and allow remote sites to embed an iFrame to display the output on their own sites. NetworkedBlogs uses this for displaying Facebook features on remote sites. iGoogle uses it extensively with their various Apps and Gadgets. It's a fairly tried-and-true method.
The advantage of using an iFrame is that you'll still have control over most of the content of the widget, but you can give end-users control over the styling (just have your iFrame application accept arguments via query variables to change colors, positions, and sizes).

Assuming the AJAX stuff is right (which I haven't confirmed): You say you can't use PHP for this - if you just mean you need it to use javascript asynchronously but can still use server code in some places, what about using PHP (or any server-side language) to do the actual work and return it to the page through AJAX/javascript - this would solve the problem Alex brings up.
So instead of getting from mysite.com/something.txt from javascript, get it from SomeAjaxHelper.php (or aspx or whatever).

For cross domain, you would have to use dynamic script tags to fetch data asynchronously. The todaysTrivia file would be a .js file that stores the data as JSON. Google for "dynamic script tags cross domain" if you want to use this technique.

Related

Web-scraping a website, that is being loaded with javascript (using javascript)

I am trying to gather line-ups from football/soccer reports. I decided to web-scrape the data from a reports provider, but their websites are loaded with javascript.
To be more specific, let's take this link to a flashscores.co.uk match.
First, they restrict CORS, which means I used allorigins.me to avoid it and then I used this code:
function readurl(url, elementID){
var url = "http://allorigins.me/get?url=" + encodeURIComponent(url) + "&callback=?";
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById(elementID).innerHTML = this.responseText;
}
};
xhttp.open("GET", url, true);
xhttp.send();
}
The result was something like this and it looks the same all the way down (still \n and \t, not the real content). I guess the problem is that the flashscores website is using javascript to load the data, but allorigins.me did not "wait" until the whole website was loaded. Here is another look, where it seems that is being loaded with javascript.
The desired result is to gather the starting elevens of both teams (Allonso M., Arrizabalaga K., Azpilicueta C.,...). I inspected the website and found, that every name is inside a HTML tag: <div class="name">PLAYER'S NAME HERE</div>.
Any idea how to avoid both problems at once?
CORS restriction
The delay before the web is "filled" with data from javascript
I am trying to use client-side languages (no PHP).
Thank you :)
There are a few problems with your question:
CORS is used to protect resources on the server side, and you need the client side resources, which are mostly public, so you do not need a way to avoid it.
The problem is not "waiting" until the page will load, the problem is you need to run these scripts yourself.
I recommend you use something like JSDom with Node.js for this task, should be quite simple.
A great blog post about web scraping with Node.js (without script execution): here
official JSDom npm page: here
Good Luck !

Loading generated text from an externally hosted PHP file into an HTML/JS animation on an iPad

We have an HTML/JS animation which is basically a fancy counter. The actual counter part is a div the value for which gets loaded from a PHP script that spits out a random number. It looks like this:
<?php
$val = file_get_contents("num.txt");
$val += rand(1, 5);
file_put_contents("num.txt", $val);
print $val;
We are hosting this PHP file on an external domain, because this animation will be packaged as part of an iPad publication. The idea is that when our animation gets loaded it will call to our PHP file and get it's value from there.
I was wondering what the most straightforward way of loading this data would be.
The div for the text part of the counter that we are changing is #Stage_Text. I've tried the following approach in the html of the animation, which unfortunately did not work:
$(document).ready(function () {
$.ajax({
url : "http://ourdomain.com/stat.php",
dataType: "text",
success : function (result) {
$("#Stage_Text").html(result);
}
});
});
Any assistance would be greatly appreciated.
I've just tested your code, and it seems to work fine.
Is you ajax request completing okay? You can check this in Firebug or your developer tools.
That's my only thought without other information.
------UDPATE-----
Sorry, I didn't see that your Ajax request was to a different domain. Yeah, this won't work because of the same-origin policy - in essence, you can only make ajax calls to the domain that served the javascript file.
Lot's of ideas to get around it here.
The easiest way is probably to use a server-side proxy.
Thanks for the responses! In the end we solved this by simply hosting the entire animation on the server and calling it within the app. This way the code I posted originally worked beautifully, and solved a few other challenges that we had - for example what happens if the user viewing the app doesn't have an internet connection? Doing it as I originally intended meant that the value would simply be blank (you could have a placeholder but it's still not ideal). With our workaround the animation simply does not get loaded and we have another, more static element underneath.
I'd say that in this particular case this is the absolutely most straightforward and easiest way to achieve what we wanted.

Bookmarklet post html contents (instead get/request)

I'd like to create a bookmarklet to take the contents of a html page and send it to an external url for processing.
Usually it would be enough to just send document.title to the server and CURL it up serverside, but for various reasons this is not an option here. I tried:
javascript:
(
function()
{
var htmlstuff=document.documentElement.innerHTML;
window.open
(
'http://127.0.0.1/grabhtml.php?url='+escape(document.location)+'&title='+escape(document.title)+'&html='+escape(htmlstuff)+'&lm='+escape(document.lastModified)
,'InfoDialog','menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=yes,dependent=no,width=400,height=480,left=50,top=50'
);
}
)
();
grabhtml.php is just
<? file_put_contents('result.html',$_REQUEST['html']); ?>
As expected Apache doesn't like such long requests:
Request-URI Too Large
The requested URL's length exceeds the capacity limit for this server.
Therefore I thought about sending the document.documentElement.innerHTML via POST instead of GET.
Firefox-WebmasterTools has an option to show the "View Generated Source" rather than the normal "View Source".
I remember last year I've read an article about how an Instapaper-like-service did exactly the same.
I've searched for days for this article, or for bookmarklet examples which POST the "Generated Source" to my form.
My Javascript skills are very basic, but I'm a quick learner. A kick into the right direction would be greatly appreciated.
You can only use POST via AJAX, so it is necessary that your JS script is running on the same domain as grabhtml.php
If it is, you can simply use jQuery for this, and it will look like:
$.post('grabhtml.php', {
url: document.location,
title: document.title,
html: htmlstuff
}, function(response) {
alert('Successfully posted.');
});
If don't, you could try to embed your script into iframe (running at the same domain as php script), send title, body, etc. from the parent frame to this iframe (via window.postMessage) and issue POST request described above ommitting cross-domain restrictions.
You can read more about window.postMessage here:
http://viget.com/extend/using-javascript-postmessage-to-talk-to-iframes
Note: I'm not sure about window.postMessage maximum message size

How to get page source of page at another domain (in Javascript!)

I am trying to get the source page of a webpage on a different domain. I know this is easily done with PHP for example but I would like to do it in Javascript because I am getting results from a page and if I use a server-side language, the original website will block the calls since they come from the same IP. However, if the calls are done on the client side, it is like the user request the results each time (different user, different IP, no original site blocking me). Is there a way to do that (even if not in Javascript but client-side).
To clarify the code I want will be applied to an HTML page so I can get the results, style them, add/delete, etc then display them to the user.
Thank you.
Modern browsers support cross-domain AJAX calls but the target site has to allow them by using special headers in the reply. Apart from that, there is no pure Javascript solution AFAIK.
Could you use an iframe? You wont have direct access to the markup to due to cross-domain restrictions, but you can still display the third-party page to the user...
window.onload = function() {
var i = document.createElement("IFRAME");
i.setAttribute("name", "ID_HERE");
i.setAttribute("id", "ID_HERE");
i.setAttribute("src", "URL_HERE");
i.style.maxHeight = "300px";
i.style.width = "100%";
document.body.appendChild(i);
}
On Windows you can use HTA
An HTA can access anything crossdomain in an iframe for example

Dashboard Cross-domain AJAX with jquery

Hey everyone, I'm working on a widget for Apple's Dashboard and I've run into a problem while trying to get data from my server using jquery's ajax function. Here's my javascript code:
$.getJSON("http://example.com/getData.php?act=data",function(json) {
$("#devMessage").html(json.message)
if(json.version != version) {
$("#latestVersion").css("color","red")
}
$("#latestVersion").html(json.version)
})
And the server responds with this json:
{"message":"Hello World","version":"1.0"}
For some reason though, when I run this the fields on the widget don't change. From debugging, I've learned that the widget doesn't even make the request to the server, so it makes me think that Apple has some kind of external URL block in place. I know this can't be true though, because many widgets phone home to check for updates.
Does anyone have any ideas as to what could be wrong?
EDIT: Also, this code works perfectly fine in Safari.
As requested by Luca, here's the PHP and Javascript code that's running right now:
PHP:
echo $_GET["callback"].'({"message":"Hello World","version":"1.0"});';
Javascript:
function showBack(event)
{
var front = document.getElementById("front");
var back = document.getElementById("back");
if (window.widget) {
widget.prepareForTransition("ToBack");
}
front.style.display = "none";
back.style.display = "block";
stopTime();
if (window.widget) {
setTimeout('widget.performTransition();', 0);
}
$.getJSON('http://nakedsteve.com/data/the-button.php?callback=?',function(json) {
$("#devMessage").html(json.message)
if(json.version != version) {
$("#latestVersion").css("color","red")
}
$("#latestVersion").html(json.version)
})
}
In Dashcode click Widget Attributes then Allow Network Access make sure that option is checked. I've built something that simply refused to work, and this was the solution.
Cross-domain Ajax requests ( Using the XMLHttpRequest / ActiveX object ) are not allowed in the current standard, as per the W3C spec:
This specification does not include
the following features which are being
considered for a future version of
this specification:
Cross-site XMLHttpRequest;
However there's 1 technique of doing ajax requests cross-domain, JSONP, by including a script tag on the page, and with a little server configuration.
jQuery supports this, but instead of responding on your server with this
{"message":"Hello World","version":"1.0"}
you'll want to respond with this:
myCallback({"message":"Hello World","version":"1.0"});
myCallback must be the value in the "callback" parameter you passed in the $.getJSON() function. So if I was using PHP, this would work:
echo $_GET["callback"].'({"message":"Hello World","version":"1.0"});';
Apple has some kind of external URL block in place.
In your Info.plist you need to have the key AllowNetworkAccess set to true.
<key>allowNetworkAccess</key>
<true/>
Your code works in Safari because it is not constrained in the dashboard sever and it is not standards complient in that it DOES allow cross site AJAX. FF IS standards complient in that it DOES NOT allow cross site ajax.
If you are creating a dashboard widget, why don't you use the XMLHttpRequest Setup function in the code library of DashCode. Apple built these in so you don't need to install 3rd party JS libraries. I'm not sure about JSON support but perhaps starting here will lead you in a better direction.
So another solution is to create your own server side web service where you can control the CORS of, the users web browser can't access another site, but if you wrap that other site in your own web service (on the same domain) then it does not cause an issue.
Interesting that it works in Safari. As far as I know to do x-domain ajax requests you need to use the jsonp dataType.
http://docs.jquery.com/Ajax/jQuery.getJSON
http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/
Basically you need to add callback=? to your query string and jquery will automatically replace it with the correct method eg:
$.getJSON("http://example.com/getData.php?act=data&callback=?",function(){ ... });
EDIT: put the callback=? bit at the end of the query string just to be safe.

Categories