views:

58

answers:

1

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));.

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.

+1  A: 

First set your bookmarklet with a link you can drop on the bookmark bar:

<html>
<head></head>
<body>
    <a href="javascript:(function(src, cb){var s = document.createElement('script');s.charset = 'UTF-8';document.body.insertBefore(s, document.body.firstChild);s.src = src;if(typeof cb === 'function'){s.onload = cb;s.onreadystatechange = function(){(/loaded|complete/).test(s.readyState)&&cb(s);};}return s;}('http://github.com/pure/pure/raw/master/libs/pure.js', function(e){alert('loaded');}))">load</a>
</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.

Mic
Hey Mic, I'm a bit confused. This is a bookmarklet we're talking about, so how would I put either script in the body to begin with? Anything I want to use, I need to inject it, right?
Joshua Cody
Hope this second take will help you.
Mic
Hey Mic, your help got me going! In my bookmarklet, I injected my secondary script via a self-executing function, and in that secondary script, I included all my JS and a self-executing function to call my method, which returns method({jsonData}). And in that same secondary script, I have a function named method(jsonp) that receives and parses the data. The only question I have left is, **why the callback function on the initial injection?**
Joshua Cody
If your JS has no dependencies and/or starts by itself, you do not need the callback.
Mic
Great, thanks for such a thorough, and well-thought answer, Mic.
Joshua Cody
Post the url here, when it is available :)
Mic