开发者

call JS function via url

i got a got a little embedded system that can be controlled via a webinterface.

the page looks like:

...
<a href="javascript:foo(bar)">foo</a>
...

is there a way to call this function just by http? like

http://<the-devices-ip>:80/jav开发者_StackOverflow社区ascipt:foo(bar) //wrong

thank you


You can do so by passing a querystring or a hash into the URL and execute a piece of JS which checks it during onload.

var query = window.location.search; // Gets '?foo=bar' from http://example.com/page.html?foo=bar
var hash = window.location.hash; // Gets '#foo' from http://example.com/page.html#foo

You only have to parse it further yourself or by using a 3rd party JS framework with plugin capabilities, like jQuery.


page1.html:

<a href="page2.html#foo('hello world')">foo</a>

page2.html:

<script type="text/javascript">
if(window.location.hash)
    eval(window.location.hash)
</script>

I'm not saying it's a good idea. It might be helpful to document why you think you need to do this, there are probably better ways to accomplish whatever the actual goal is.

Note that doing this will not allow you to pass variables around. You need to have only static values in the javascript code executed on page2.html, or generate the href in page1.html dynamically.


Caveat: this will potentially open up your code to HTML and/or script injections. Filter rigorously.

I recently had to do something similar for a project that I was contracted out on. Like others, I used the hash portion of the URL to pass in JavaScript functions and parameters. However, the main difference was that I didn't do a simple eval of the entire string. I established a specific format to 1) narrow the amount of functions that could be executed, and 2) sanitize any input that the method required

The format, in full, is as follows:

http://somedomain.tld/path/?query=blah#specific.controller.object/method/['array', 'of', {json: 'arguments'}]

So, basically, you end up with the following string:

specific.controller.object/method/['array', 'of', {json: 'arguments'}]

I then wrote a parser to handle this string. Restrictions where exacted over what objects could be called by prepending with a sort of "namespace" object, in other words, calling it as part of a member of an existing, predetermined static object. For example, specific.controller.object, would be called as new com.project.specific.controller.object();. Here's something similar to my parser:

var data       = location.hash.substr(1).split('/'),
 controller = ("my.namespace." + data[0]).split("."),
    // You can provide a default method if you want, my framework used `show`
 method     = data[1] || "show",
    // must be an array for use with `apply`
 params     = data[2] || "[]"; 

// Parse the controller to find the appropriate object to instantiate.
// All objects are in reference to the global window object.  Break 
// them apart by their dot composition and step down through the object 
// tree starting at window.
var composition = window;
for ( var i=0; i<controller.length; i++ ) {
    composition = composition[ controller[i] ];
}

var obj = new composition;

// Handle the parameters.  It may be the case that there "/" is present 
// in the last argument. If so, add anything that was left out.
if ( data.length > 3 ) {
    for ( var i=3; i<data.length; i++ ) {
        params += '/' + data[i];
    }
}

// Convert params from a string to an array.  
// ***Possible injection point here***
params = dojo.fromJson(params);

// Make sure that the method runs in the proper context and
// pass it all of the parameters
obj[method].apply(obj, params);

Because the way the parser works, you required to provide parameters if none are needed, and in some cases, if you choose to allow default methods as I have, you don't have to specify which member on the object to call, which simplifies that construction of these URL's greatly.

Instead of using a static namespace object to restrict what objects could be instantiated, it would be trivial to use a white list of safe objects and methods.


<a href="javascript:foo(bar)">foo</a> represents the calling of a function, not the call to a url. There is no direct mapping between a url and a JavaScript function.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜