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.
Related
I have a portion of my web application that uses AJAX. I am using the JQuery AJAX call to add and remove items from the users shopping cart, and it works fine. The URL that I pass as a parameter in the AJAX call is the url-mapping defined in the web.xml file, minus the leading forward slash.
I tried to replicate this with another place in the application where I would like to use AJAX, but this time, the Servlet GET is not even being called at all. I have alerts in the javascript function, so I know the function is being called. Is there a way that I can see (within the ajax function call) what the fully qualified URL is that the GET request is being made to? Also, what is the 'rule' with respect to the AJAX URL? Is there a way that I can get to the context root? My Servlet is mapped to www.mydomain.com/contextRoot/un
I would rather not have to hardcode the context root into the function call, that way if it ever changes, I don't have to update all my javascript functions.
The "rule"
Ajax requests (or any http request from the page) that does not start with a / (or the full domain path) is relative to the current HTML file path.
How to view GET requests
Use the debugging tools in Chrome/Firefox or something like Fiddler2
How to get server root
If it is a simple www.host.com:
var root = location.protocol + '//' + location.host;
(Not sure if this works for context based domains).
You do not mention what server technology you are using, but if you are using MVC/Razor you can inject the server root into a Javascript variable with something like this in your master page header:
<script type="text/javascript>
window.domainRoot = "#(Url.Content("~/"))";
<script>
this injects a javaScript line like:
window.domainRoot = "http://www.mydomain/mycontext/";
you can then reference window.domainRoot from any JavaScript code.
If you are using PHP there will be an equivalent way to inject the server root.
A simple browser debugger (F12) and you can read the network traffic send.
From here it is possible to see all the details (sent and/or received)
I think The url plus parameter is contextRoot/un?para=*.
I was recently approached by a web partner and they asked me to add their 'tracking code' to my site as shown below. The data and address would be different, but the structure is the same as below. Currently they load our site in an IFrame and what I can't understand is...
How could the script portion provide any value to them? Can a parent page read JavaScript state of something in a hosted IFrame? Google uses a similar pattern but they set the src which has Script that is executed when the page loads and could read the state.
Can anyone explain how this might be working or is this just useless page spam?
<img src="https://www.APartnerCompany.foo/thing.img?arg=value" />
<script type="text/javascript">
//<![CDATA[
var Foo = {};
Foo.Tracking = {};
Foo.Tracking.Sale = {};
Foo.Tracking.Sale.amount = '100.00';
//]]>
</script>
An inline script can also read values from the page it is contained in. To post them back to their own server, they seem to use the src attribute of that affiliate image. However, the pieces you provided are harmless (the code does nothing than constructing an object) and requests only a non-executable from https://www.APartnerCompany.foo/thing.img?arg=value (beeing logged at theirs).
When the request for that src is being sent the server is just logging the variables that are accompanied with it, the JS code is just updating the arguments with relevant data.
All it does is send information to a server through a GET request which it is logged. It can be as simple as reading the Apache logs for hits or it can be a cgi that processes the data. That is basically how all those ad/logging services work.
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.
I read (somewhere else on this site) you can't reload (or inject javascript) onto a page that is already rendered.
Is there any other way of doing this. For instance an iFrame?
I have a recent comment widget.js and I need to constantly get it to reload without reloading the whole page.
Any ideas?
edit: The site has recent comments on it and they are displayed via a recentcomment.js
Once the page is loaded it doesn't update itself unless you reload the page. I want it to update itself, a way to do this is to just reload the js file on the page, correct?
Why do you need to do this? It seems to me that there's probably a more appropriate solution to your problem.
But to answer it:
var elm = document.createElement("script");
elm.src = "Widget.js";
document.getElementsByTagName("head")[0].appendChild(elm);
Hope I didn't write any mistakes...
Rather than reloading the file, you can have all the implementation of the file contained in a function and then call the function every minute using the setTimeout() function.
Alternatively, if you want to reload it because the content of the file might have changed, it would probably be better to move that part of the code out to some external file and then use a function (running every minute with setTimeout()) to load the new content you need.
You can make cross-domain AJAX requests using certain methods, so you could make an AJAX request for the script file and parse it yourself. Parsing it yourself probably isn't an optimal solution, but it looks like you're dealing with a brain-dead service provider anyways.
Look at this guy's jQuery mod for an example:
http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/
Once you get the data from the 3rd party, you could probably use some combination of regex and JSON parser to extract the comments.
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.