accessing json object with javascript (no var) - dynamically called in file (experiment) - javascript

I am creating a page which calls dynamic content from the web with javascript and obviously run into a snag with the SOP (same origin policy) I know this would not work on a production page as the calls would need to be checked on the server but I have it at a point where it practically works but I cant access the data. I would really like to know if it is possible.
The code below adds the URL to the file:
var url = 'http://theSite.com/?query=' + userInput + '&othercode';
var script = document.createElement('script');
script.setAttribute('src', url);
script.setAttribute('type', "application/json");
script.setAttribute('id', "special");
document.getElementsByTagName('body')[0].appendChild(script);
This adds the following to my html:
<script src="http://theSite.com/?query=userInput&othercode" type="application/json" id="special"></script>
Now the problem:
How do I access the resulting data?
I get a JSON script but dont know how to attach it to a variable in Javascript or use it!
the code arrives in this basic format:
{"count":5,"results":[{"name":"value","id":"value2", ..... }], ... "code":200}
How do I access the data or assign it to a variable?
(I have not yet tried jQuery and know it will probably be easier but if anyone can help with this code that would be great rather than trying to do this all again in jQuery).

You need to have control of the service you're calling (theSite.com). One option is to make it return JSONP instead of JSON:
dataCallback({"count":5,"results":[{"name":"value","id":"value2", ..... }], ... "code":200});
Or, make your script inside an iframe that is served from theSite.com, and use postMessage to communicate its result back to your window.
Otherwise... well, you're doing exactly what SOP is looking to prevent, so the chances are grim, AFAIK.
Oh, one more option: make an AJAX call to your server, which will make the service call and pass the data to you. Servers are not restricted like clients are.

Related

How to create a tracking script similar to Google analytic with js and php?

I want to create a tracking script. Something similar with Google Analytic but very basic.
The requirements are
I need simple js script like Google Analytic does
make most of the logic inside the js file from the main site
collect in PHP the information and store it
What I can't figure yet is what are the ways to do this? Google from what I see is loading a gif file, stores the information and parses the logs. If I do something similar sending the data to a php file Ajax cross site policy will stop me, from what I remember.
Not sure on how Google Analytics does things, but the way to circumvent the x-site policy is, simply, don't do an Ajax call. Suppose you used javascript and now have an hash with your visitor's data:
var statsPage = 'http://mysite/gather_stats.php';
var stats = {
page: location.href,
browser: 'ie',
ip: '127.0.0.1',
referral: 'google.com?search=porn'
};
var params = $.param(stats); // serializes it https://api.jquery.com/jQuery.param/
now you only have to do a GET request to you php page with this string as a parameter, don't use Ajax tho, simply use the url as an img src
$('<img>', {
src: statsPage + '?' + params
}).appendTo('body').remove()
you may as well use a script tag the same way, but you should pay attention because anything the php stats page returns will be executed as javascript (which is exactly how jsonp works).
Bear in mind that some limits apply to Get strings length.

Access a cgi Script Via a JavaScript

I am trying to make a link where when it is clicked, it goes to the site it is supposed to, but it also runs a cgi script. I have found different examples, but I still don't fully understand it.
In essence, I have two questions:
Where can I host the script so I can access it?
How do I access it?
Where can I host the script so I can access it?
If you want to access it from JavaScript then it has to be on the same origin (i.e. hostname and port) as the page the JavaScript is running in.
How do I access it?
You can either forget JavaScript, have a regular link and then have the CGI perform a 302 redirect, or you can use Ajax.
Beware of timing issues. It is possible for the browser to go to the next URL before it gets around to making the Ajax request. A redirect would probably be a better approach.
<script>
function callYourCGI(){
var i = new Image();
i.src = "your-cgi-url?name=value&name2=value2";
}
</script>
<a href="the-next-document.html" onclick="callYourCGI()">
The Image object is part of the HTML DOM. It allows you to manipulate images in an HTML page. Read about it here: http://www.javascriptkit.com/jsref/image.shtml
The script is creating an image object and then assigning the URL of your CGI script to the SRC attribute. This makes the browser perform a get request for the content of the URL. In this case, you aren't going to display the image object, so the content returned by your CGI script need not be a real image. If can be, if you want, though. Either way, the side-effect is that your CGI script is called, with some parameters if desired. An advantage of this method is that it does not violate the same origin policy, since images are allowed to be loaded from anywhere.

How to make a javascript like Disqus or IntenseDebate

I want to make an app that can display on any webpage, just like how Disqus or IntenseDebate render on articles & web pages.
It will display a mini-ecommerce store front.
I'm not sure how to get started.
Is there any sample code, framework, or design pattern for these "widgets"?
For example, I'd like to display products.
Should I first create a webservice or RSS that lists all of them?
Or can one of these Ajax Scripts simply digest an XHTML webpage and display that?
thanks for any tips, I really appreciate it.
Basically you have two options - to use iframes to wrap your content or to use DOM injection style.
IFRAMES
Iframes are the easy ones - the host site includes an iframe where the url includes all the nessessary params.
<p>Check out this cool webstore:</p>
<iframe src="http://yourdomain.com/store?site_id=123"></iframe>
But this comes with a cost - there's no easy way to resize the iframe considering the content. You're pretty much fixed with initial dimensions. You can come up with some kind of cross frame script that measures the size of the iframe contents and forwards it to the host site that resizes the iframe based on the numbers from the script. But this is really hacky.
DOM injection
Second approach is to "inject" your own HTML directly to the host page. Host site loads a <script> tag from your server and the script includes all the information to add HTML to the page. There's two approaches - first one is to generate all the HTML in your server and use document.write to inject it.
<p>Check out this cool webstore:</p>
<script src="http://yourdomain.com/store?site_id=123"></script>
And the script source would be something like
document.write('<h1>Amazing products</h1>');
document.write('<ul>');
document.write('<li>green car</li>');
document.write('<li>blue van</li>');
document.write('</ul>');
This replaces the original <script> tag with the HTML inside document.write calls and the injected HTML comes part of the original page - so no resizing etc problems like with iframes.
<p>Check out this cool webstore:</p>
<h1>Amazing products</h1>
<ul>
<li>green car</li>
<li>blue van</li>
</ul>
Another approach for the same thing would be separating to data from the HTML. Included script would consist of two parts - the drawing logic and the data in serialized form (ie. JSON). This gives a lot of flexibility for the script compared to the kind of stiffy document.write approach. Instead of outpurring HTML directly to the page, you generate the needed DOM nodes on the fly and attach it to a specific element.
<p>Check out this cool webstore:</p>
<div id="store"></div>
<script src="http://yourdomain.com/store_data?site_id=123"></script>
<script src="http://yourdomain.com/generate_store"></script>
The first script consists of the data and the second one the drawing logic.
var store_data = [
{title: "green car", id:1},
{title: "blue van", id:2}
];
The script would be something like this
var store_elm = document.getElementById("store");
for(var i=0; i< store_data.length; i++){
var link = document.createElement("a");
link.href = "http://yourdomain.com/?id=" + store_elmi[i].id;
link.innerHTML = store_elmi[i].title;
store_elm.appendChild(link);
}
Though a bit more complicated than document.write, this approach is the most flexible of them all.
Sending data
If you want to send some kind of data back to your server then you can use script injection (you can't use AJAX since the same origin policy but there's no restrictions on script injection). This consists of putting all the data to the script url (remember, IE has the limit of 4kB for the URL length) and server responding with needed data.
var message = "message to the server";
var header = document.getElementsByTagName('head')[0];
var script_tag = document.createElement("script");
var url = "http://yourserver.com/msg";
script_tag.src = url+"?msg="+encodeURIComponent(message)+"&callback=alert";
header.appendChild(script_tag);
Now your server gets the request with GET params msg=message to the server and callback=alert does something with it, and responds with
<?
$l = strlen($_GET["msg"]);
echo $_GET["callback"].'("request was $l chars");';
?>
Which would make up
alert("request was 21 chars");
If you change the alert for some kind of your own function then you can pass messages around between the webpage and the server.
I haven't done much with either Disqus or IntenseDebate, but I do know how I would approach making such a widget. The actual displaying portion of the widget would be generated with JavaScript. So, say you had a div tag with an id of commerce_store. Your JavaScript code would search the document, when it is first loaded (or when an ajax request alters the page), and find if a commerce_store div exists. Upon finding such a container, it will auto-generate all the necessary HTML. If you don't already know how to do this, you can google 'dynamically adding elements in javascript'. I recommend making a custom JavaScript library for your widget. It doesn't need to be anything too crazy. Something like this:
window.onload = init(){
widget.load();
}
var widget = function(){
this.load = function(){
//search for the commerce_store div
//get some data from the sql database
var dat = ajax('actions/getData.php',{type:'get',params:{page:123}});
//display HTML for data
for (var i in dat){
this.addDatNode(dat[i]);
}
}
this.addDatNode = function(stuff){
//make a node
var n = document.createElement('div');
//style the node, and add content
n.innerHTML = stuff;
document.getElementById('commerce_store').appendNode(n);
}
}
Of course, you'll need to set up some type of AJAX framework to get database info and things. But that shouldn't be too hard.
For Disqus and IntenseDebate, I believe the comment forms and everything are all just HTML (generated through JavaScript). The actual 'plugin' portion of the script would be a background framework of either ASP, PHP, SQL, etc. The simplest way to do this, would probably just be some PHP and SQL code. The SQL would be used to store all the comments or sales info into a database, and the PHP would be used to manipulate the data. Something like this:
function addSale(){ //MySQL code here };
function deleteSale(){ //MySQL code here };
function editSale(){ //MySQL code here };
//...
And your big PHP file would have all of the actions your widget would ever need to do (in regards to altering the database. But, even with this big PHP file, you'll still need someway of calling individual functions with your ajax framework. Look back at the actions/getData.php request of the example JavaScript framework. Actions, refers to a folder with a bunch of PHP files, one for each method. For example, addSale.php:
include("../db_connect.php");
db_connect();
//make sure the user is logged in
include("../authenticate.php");
authenticate();
//Get any data that AJAX sent to us
var dat = $_GET['sale_num'];
//Run the method
include("../PHP_methods.php");
addSale(dat);
The reason you would want separate files for the PHP_methods and run files, is because you could potentially have more than one PHP_methods files. You could have three method API's, one for displaying content, one for requesting content, and one for altering content. Once you start reusing your methods more and more, its best to have them all in one place. Rewritten once, rewritten everywhere.
So, really, that's all you'd need for the widget. Of course, you would want to have a install script that sets up the commerce database and all. But the actual widget would just be a folder with the aforementioned script files:
install.php: gets the database set up
JavaScript library: to load the HTML content and forms and conduct ajax requests
CSS file: for styling the HTML content and forms
db_connect: a generic php script used connect to the database
authenticate: a php script to check if a user is logged in; this could vary, depending on whether you have your own user system, or are using gravitars/facebook/twitter/etc.
PHP_methods: a big php file with all the database manipulation methods you'd need
actions folder: a bunch of individual php files that call the necessary PHP methods; call each of these php files with AJAX
In theory, all you'd have to do would be copy that folder over to any website, and run the install.php to get it set up. Any page you want the widget to run on, you would simply include the .js file, and it will do all the work.
Of course, that's just how I would set it up. I assume that changes in programming languages, or setup specifics will vary. But, the basic idea holds similar for most website plugins.
Oh, and one more thing. If you were intending to sell the widget, it would be extremely difficult to try and secure all of those scripts from redistribution. Your best bet would be to have the PHP files on your own server. The client would need to have their own db_connect.php, that connects to their own database and all. But, the actual ajax requests would need to refer to the files on your remote server. The request would need to send the url of the valid db_connect, with some type of password or something. Actually, come to think of it, I don't think its possible to do remote server file sharing. You'd have to research it a bit more, 'cuz I certainly don't know how you'd do it.
I like the Azmisov's solution, but it has some disadvantages.
Sites might not want your code on their servers. It'd be much better if you would switch from AJAX to loading scripts (eg. jQuery's getJSON)
So I suggest:
Include jquery hosted on google and a short jquery code from your domain to the client sites. Nothing more.
Write the script with cross-domain calls to your server (through getJSON or getScript) so that everything is fetched directly and nothing has to be inctalled on the client's server. See here for examples, I wouldn't write anything better here. Adding content to the page is easy enough with jQuery to allow me not mentioning it here :) Just one command.
Distribute easily by providing two lines of <script src= ... ></script>

JSONP for cross-site bookmarklet guidance

I'm looking to build a cross-site bookmarklet that gets a highlighted word, passes it to a CodeIgniter method (domain.com/controller/method), and returns the definition via a dictionary API. I've got a skeleton working well on a single domain, but I'm looking to expand it to use JSONP cross-domain. But I feel unclear.
I know I need to load a script from a remote location and inject it in the current context. And I believe I'll need to get the highlighted word on a page, then call a URL that looks like domain.com/controller/method/word to get that script. Then it gets foggy.
I think I essentially have two questions:
Where do I include the necessary javascript to handle the parsing and passing of the word via XMLHTTPRequest? I think this will be the SRC of the script that I'll inject in the new context. Is this somehow within my relevant CodeIgniter method? Or does this new script come from a random location on the same server as the relevant method and simply call to it?
Answer: This is not supplementary to XMLHTTPRequest, this is in lieu of it, so that step is completely removed. The new script calls to the method, passes requisite information via query strings, and receives the JSON array in response.
Am I correct in understanding I'll eventually pass the JSON response from the method back as word(json_encode($array));?
Answer: Yes, I'll pass that back as callbackFunctionName(json_encode($array));.
Do I need to set headers, as done here?
Update
I included the answers to two of my three answers above. If someone can explain things thoroughly, of course I'll mark their answer as correct, else I'll elaborate my stumbling blocks in an answer. I still have no idea where I write the callback function and what I'll be doing with that in JS.
Thanks so much for any help you can give on this.
First set your bookmarklet with a link you can drop on the bookmark bar:
<html>
<head></head>
<body>
load
</body>
</html>
Replace the url by your script, it will be loaded and running on the host page.
However it sits now in the hosted page, and can't call your server with XMLHTTPRequest as the domains do not match.
Here comes JSONP.
In the loaded script, you can put a function eg: function srvCallback(json){...}
When you want to call your server you will inject it as a script using a similar function as in the bookmarklet above:
function jsonp(src){
var s = document.createElement('script');
old = document.getElementById('srvCall');
old && document.body.removeChild(old);
s.charset = 'UTF-8';
s.id = 'srvCall';
document.body.insertBefore(s, document.body.firstChild);
s.src = src + '?' + new Date().getTime();
}
Inject your request, eg:
jsonp('http://domain.com/controller/method/word')
The server should respond something like:
srvCallback({word:'hello'});
And finally the function srvCallback is automatically called, inside the function you get your JSON and show the result to the user.

Script puzzle <script src="ajaxpage.php?emp_id=23" />?

Very simple Ajax request taking employee id and returning the user info as HTML dumb.
Request ajax("employee/info?emp_id=3543")
Response id = 3543name = some name
This is just another simple JS trick to populate the UI. However i do not understand how something like below is equally able to execute correctly and dump the HTML code.
<script type="text/javascript" src="employee/info?emp_id=3543" />
When page encounters following code it executes like the ajax request is executed and dumps code into page. Only difference is its no more asynchronous as in case of Ajax.
Questions :
Is this correct approach ? its +ves and -ves.
Which are the correct scenarious to user it?
Is this also means that any HTML tag taking "src" tag can be used like this?
I have used this kind of javascript loading for cross domain scripting. Where it is very useful. Here is an example to show what I mean.
[Keep in mind, that JS does not allow cross domain calls from javascript; due to inbuilt security restrictions]
On domain www.xyz.com there lies a service that give me a list of users which can be accessed from http://xyz.com/users/list?age=20
It returns a json, with a wrapping method like following
JSON:
{username:"user1", age:21}
If I request this json wrapped in a method like as follows:
callMyMethod({username:"user1", age:21})
Then this is a wrapped json which if loads on my page; will try to invoke a method called callMyMethod. This would be allowed in a <script src="source"> kind of declaration but would not be allowed otherwise.
So what I can do is as follows
<script language="javascript" src="http://xyz.com/users/list?age=20"></script>
<script language="javascript">
function callMyMethod(data)
{
//so something with the passed json as data variable.
}
</script>
This would allow me to stuff with JSON coming from other domain, which I wouldn't have been able to do otherwise. So; you see how I could achieve a cross domain scripting which would have been a tough nut to crack otherwise.
This is just one of the uses.
Other reasons why someone would do that is:
To version their JS files with
releases.
To uncache the js files so that they are loaded on client as soon as some changes happen to js and params being passed to URL will try to fetch the latest JS. This would enable new changes getting reflected on client immediatly.
When you want to generate conditional JS.
The usage you have specified in example wouldn't probably serve much purpose; would probably just delay the loading of page if processing by server takes time and instead a async ajax call would be much preferred.
Is this correct approach ? its +ves
and -ves.
Depends whether you want to use asynchronous (ajax) way or not. Nothing like +ve or -ve.
The later method takes more time though.
Which are the correct scenarious to
user it?
Ajax way is the correct method there in that sense.
Is this also means that any HTML tag
taking "src" tag can be used like
this?
src is used to specify the source path. That is what it is meant to do.

Categories

Resources