Loading external JSON file as a javascript variable - javascript

I thought this question would be trivial but I just can't seem to find an answer.
A website (different origin, no control over it) is making available some JSON files. I want some variables of my script to grab the content of those files. I don't care whether it is done synchrnously or not. How would you go ?

using JSONP consist of using your url, with parameters, and add a script file to your page
www.example.com/process?value=1&callback=Func
add the script to your page.
var url = "www.example.com/process?value=1&callback=Func";
var script = document.createElement('script');
script.type= ' text/javascript';
script.src = url;
document.getElementsByTagName("body")[0].appendChild(script);
now you can use the call back function or access the variables that were added from this script.
UPDATE
At the end of your jsonp script you can call your call back function
Ex: php
<?php
if (isset($_GET['callback'])) {
echo $_GET['callback']."();";
// Func(); // will call your function and use your variables.
}

If the remote host does not supply JSONP or CORS, then you will need to place a server-side component on your own domain which fetches the JSON for you and serves it locally.

Related

create callback API

New Restful API's like Google, OpenStreetview use a simple call back mechanism.
Basically you call the API, adding a parameter &callback=my function.
When executing a call to this API, as a result my function is called passing a JSON dataset.
I am trying to create the same mechanisme for a API I am building for my personal use.
As far as I understood my API needs to return a javascript, that calls the function that is passed in a script.
For a test I created this:
function apiCall(URL,values, keyPair,cBackPair) {
// URL specifics URL to call
// keyPair: <keyname>=<key>; leave black if unneeded
// cBacPair: <callBackParametername>=<functionname>
// called is: URL?values&keypair&cBackPair
var request = (keyPair)?'&'+keyPair:'';
request = URL + '?'+ encodeURI(values) + request + '&' + cBackPair;
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", request);
document.body.appendChild(script);
}
function callAPI() {
apiCall('http://xllent.nl/map/ajax/answer.php','q=one','','s=doit');
}
function doit(result) {
alert(result);
}
To test I call callAPI onload.
The script answer.php is very basic:
<?$s = $_GET['s'];
?>
<script type="text/javascript">
doit('jeroen');
</script>
Later the script would use $s to call the right script, and of course supply user data.
For now I am just trying to get the script doit('jeroen'); to be run. But nothing happens.
Typing javascript:doit('jeroen'); in the browser window gives the result I would expect.
Any suggestions?
Don't surround your javascript with <script> tags. You are not generating a HTML file with a javascript body.. You should think of this as if you're generating a javascript file on fly.
Javascript files also don't start and end with <script>

Methods to invoke remote scripts

Scenario
A page invokes a remote script available at this url: http://url.to.script/myScript?ScriptParamsList. Let's assume that:
Async execution is not required.
Displaying output is not required.
The script is called on a button click event. Let Handler() be the javascript event handler:
function Handler()
{
//invoke the remote script
}
Several methods are available to implement Handler() function:
script vs img tag:
document.write('<script src="http://url.to.script/myScript?ScriptParamsList" type="text/javascript"></script>');
document.write('<img src="http://url.to.script/myScript?ScriptParamsList" />');
jQuery .html() vs .load():
$('#TargetDiv').html('<img src="http://url.to.script/myScript?ScriptParamsList" />');
$('#TargetDiv').load('http://url.to.script/myScript?ScriptParamsList');
Question
Which are the advantages and the disadvantages?
document.write will replace your current document when it's called after the document is loaded. Never use this method.
Using <script> allows you to fetch a request from an external domain, without being hindered by the same origin policy. Additionally, in the server's response, you can add and execute JavaScript, which might be useful.
Using .html('<img ...>') makes no sense, unless your server returns an image with meaningful data. If you intend to only trigger a server request, the following would be better:
new Image().src = 'http://url.to.script/myScript?...';
$('..').load is not going to work if the URL is located at a different domain, because of the same origin policy.
I vote for the new Image().src = '..'; method. If you dislike this syntax, and want more jQuery, use:
$('<img>').attr('src', 'http://...');
Note: The result may be cached. If you don't want this to happen, append a random query string, to break the cache (eg. url = url + '&_t=' + new Date().getTime()).

Inject local .js file into a webpage?

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

Access and change the attributes of <script> tag

How can I access and change the attributes of tag, specially the src?
something like this maybe:
document.scripts[i].src
of course it does not work!
I intend to alter it this way:
document.scripts[i].src += '?ver3'
in a loop for all the script on the page.
You could use document.getElementsByTagName('script') to get all the script elements in the page.
However, any script elements that you find will already have loaded their content, so it will be too late to change the URL that they use to load content.
If you want to alter the URLs, you should use a solution on the server side, so that the URLs are changed when they arrive to the browser.
With jQuery:
jQuery("script").each(function(){
var old_src = jQuery(this).attr('src');
jQuery(this).attr('src', old_src+'?ver3');
})
With good-old JS:
var scripts = document.getElementsByTagName('script');
for (var i=0; i<scripts.length; i++){
var old_src = scripts[i].getAttribute('src');
scripts[i].setAttribute('src', old_src +'?ver3');
}
Install httpd (Apache) and PHP.
Put into your hosts file (or hosts.txt) this line:
127.0.0.1 example.com
Write an php script named index.php and put it into server directory (/var/www/html or some like this; depends on configuration).
When you load in web browser http://example.com you will be redirected to 127.0.0.1 (your local server) and in PHP this variable $_SERVER["HTTP_HOST"] will be set to example.com.
Get this site (e.g. using cURL), change what you want (using string functions, regex, DOMDocument, SimpleXML, etc.) and send modified content to browser.
That's all. :)

For every AJAX call I make, I would like to reload a new java-script

Basically, everytime anybody does anything on this website, I need to retrieve a new javascript from the server (it is a complex math thing, and I am not concerned with speed).
I make the AJAX call, and stick it in the browser in a tag, like this:
getandplaceajax('id=showtotals','main'); // The first is the URL parameter, and the second is the ID of the <div> tag.
While I am doing this, I would like to re-write the java-script file, on the server, and then reload it. It is like this, in the tag.
<script type="text/javascript" src="randomfilename.js"></script>
After this I refresh my object thusly, by retreiving new XML data:
object1.loadXML("http://mywebsite/mydata.xml",
function(xml, url) {eventSource.loadXML(xml,url); });
How do I tell the browser to re-load the java-script file (force a re-load, on demand)?
I tried to interactively load the java-script into the portion of the page, but this is an iffy situation given that AJAX is asynchronous and unpredictable in the event chain.
And I am not doing page loads, so referencing the java-script with a unique number parameter (to prevent caching) isn't an option.
An extra $50 in the church offering plate next Sunday, in your name, for a solution.
Thanks in advance
Jeff
There is no need to make an Ajax call if you just need to load a JavaScript file. You can just append a new script tag to the page.
var scr = document.createElement("script");
scr.type="text/javascript";
scr.src="myFile.js";
document.body.appendChild(scr)
If you are calling the same file each time you need to force it to fetch the new file by adding a querystring value
scr.src="myFile.js?ts=" + new Date().getTime();
On the server you can request a php, servlet, .NET page, etc and have it return the JavaScript code. It does not have to be a js file. Just set the content type to be JavaScript and your browser will not care.
If you are not using any library, you can use what Facebook is doing
http://developers.facebook.com/docs/reference/javascript/
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol +
'//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
to load in a new script this way. You can also change the src of the script tag, to something like 'myfile.js?timestamp=' + (new Date()).getTime(), or you can return javascript with <script> tag around it and put it into a div or return javascript and eval them, similar to how RJS is handled.

Categories