Hacker News new | past | comments | ask | show | jobs | submit login
Simple Way to Extract GET Params from a JavaScript Script Tag (loopj.com)
36 points by immad on June 12, 2010 | hide | past | favorite | 25 comments



This fails if you can't control the filename of the script being hosted. You can get around said flaw by utlizing the magic of errors™ as demonstrated in this example function I have made:

    var getErrorLocation = function (error) {
        var loc, replacer = function (stack, matchedLoc) {
            loc = matchedLoc;
        };
    
        if ("fileName" in error) {
            loc = error.fileName;
        } else if ("stacktrace" in error) { // Opera
            error.stacktrace.replace(/Line \d+ of .+ script (.*)/gm, replacer);
        } else if ("stack" in error) { // WebKit
            error.stack.replace(/at (.*)/gm, replacer);
            loc = loc.replace(/:\d+:\d+$/, ""); // remove line number
        }
        
        return loc;
    };
You could use it as such:

    try {
        0();
    } catch (e) {
        var scriptLocation = getErrorLocation(e);
    }
In SpiderMonkey and Rhino, the Error constructor itself is magic too, so you could just do getErrorLocation(new Error) instead.


I was seeking to avoid the same thing recently. Instead of adding more JavaScript, I decided to use PHP. While we're using Rails, it's very inefficient to fire up the whole engine to do something as simple as outputting a script with a few interpolated variables. A simple PHP script can put out 2-3 times as many requests per second as Rails/Django for a task like that.


Rack Metal was pretty much made for that. I wouldn't use either until I had evidence that it was a bottleneck, but if you do, then it would let you do a few simple requests quickly without needing to swap stacks. (I run PHP and Rails concurrently for one application, but only because I had to be able to get Wordpress working.)


If you must do this, use # so the browser can cache the script across clients.


Here's a simpler way. Put this in your htaccess file:

    AddHandler server-parsed .js
then add:

    (function(query_string){
    ...
    })("<!--#echo var="QUERY_STRING" -->");
around your script. This obviously has problems with caching, but it doesn't have the problems addressed with those "heavy loads" that you have with PHP et al.


The beauty of doing this statically entirely in javascript is that you can serve the js file from anywhere, including s3 for example.


The beauty of doing this with SSI is that you can include the same script multiple times, but with different parameters, and get: different effects.


Holy XSS injection, Batman!


QUERY_STRING isn't decoded. What am I missing here?


This solution fails when you need to insert the script more than once in a page. Instead, browsers really should provide scripts a means to retrieve the script element that they belong to.


A comment on the article pointed out that since javascript execution is blocking, you can do that for synchronous javascript:

  scripts=document.elements.getElementByTagName('script')
  latest=scripts[scripts.length-1]


I wrote a small jQuery plugin around that idea ( at https://gist.github.com/435668/85466138a24814baef3ec6a73b7cc... )

This approach allows you to specify parameters as JSON. So data of arbitrary length can be passed without having to resort to some global variable.

It solves a problem I had where I needed to pass some template engine generated content into an otherwise static script.

Thanks for the tip :)


Right, but then you have to require that your script be loaded synchronously. And this is really just a hack to get around the fact that browsers don't provide a proper API.


You can use a static counter to get around that


Sorry, can you explain what you mean?


fyi, this has been used in http://script.aculo.us/ (the effects js library for prototype) from a couple years ago.

example usage: <script src="scriptaculous.js?load=effects,dragdrop"></script>

code is here: http://script.aculo.us/scriptaculous.js


Doesn't support multiple keys with the same name, which is valid and not particularly uncommon. I wouldn't be surprised if it breaks in other ways. This kind of thing is always full of subtle pitfalls.


You'd normally use this script when you were in full control of the parameters you are passing, so its fairly easy to avoid this situation.


multiple keys with the same name? what do you mean? arrays?


There's no such thing as parameter arrays. Any parameter name can have multiple values. PHP just happens to turn those into arrays. (I've never tried it in PHP with a parameter name that didn't have brackets at the end. It might not work in PHP.)

If you're familiar with Django, this is why the GET, POST and other request dictionaries are actually MultiValueDicts. If you call request.GET.getlist('varname') instead of request.GET['varname'], you'll get a list of each value passed with that name. The brackets aren't special, and if you used them, you'd need request.GET.getlist('varname[]').


I think he means duplicate keys, as in '?id=4&color=8&id=6'


you can also do this with a regular expression. here's the blog post i wrote on it a year ago. i use one function to grab get variables from either window.location or from a script tag. 5 lines of code.

http://www.onlineaspect.com/2009/06/10/reading-get-variables...


It would be nice if the game bar at the bottom wasn't broken and hovering right over the content of the post. I'm on an iPad.


How has this been upvoted? Isn't this what meta tags were made for?

<meta name=key content=123/>


I love code-heavy posts, but damn I hate lines with a bunch of javascript all bunched together with semicolons between statements.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: