Web2py: Pass a variable from view to controller

2019-04-15 00:59发布

问题:

How can I pass a JavaScript variable from the view to Python in controller? I don't want to use request.vars or request.args, because that would allow to user to give arbitrary parameters for the action by typing it into the address bar.

Example view:

<button onclick='myFunction();'>Execute</button>
<script>
    function myFunction();{
        var value = calculateValue();
        //pass value to my_action
        window.location = 'my_action';
    }
</script>

Example controller:

def index():
    return dict()

def my_action():
    #retrieve passed variable
    #handle the variable 
    #...
    redirect(URL('index'))

回答1:

You could make an Ajax call:

<script>
    function myFunction();{
        var value = calculateValue();
        ajax('{{=URL('default', 'my_action')}}' + '?value=' + value, [], ':eval');
    }
</script>

Followed by a client-side redirect once the Ajax response is returned:

def my_action():
    value = request.vars.value
    # handle the variable 
    redirect(URL('index'), client_side=True)

Note, however, that even with this method, someone could still make a manual request to /default/my_action?value=some_value to send arbitrary data to your function (of course, they would have to be a little more technically savvy to do so, as the above URL would never appear in the browser address bar for them to observe -- they would have to inspect your code or watch the network traffic to figure out what request to make).

In general, if you are calculating a value in the browser and then submitting it to the server via an HTTP request, there is no way to prevent a knowledgeable attacker from submitting some arbitrary data rather than the value calculated by your Javascript code. Your best bet is to instead focus on doing some server-side validation of the input data, or move the calculation to the server (though presumably the calculation is based on some input that must ultimately come from the browser and therefore be validated in some way).