0

Seems that every parameters passed in a http request is a string type.
So, if I want to pass two values that are, for example, boo = true and str = "true" they will be encoded in the same way:

/server/test?boo=true&str=true.

I don't know if there is something that I'm doing wrong, but if it's so, I guess it can be very frustrating to deduce everytime the type of a parameter on the server side as it can cause type misunderstanding on server side.
I found the same issue even in php and in nodejs. The weird thing is that when instead the server returns a json stringified value, it works perfect on javascript and parameters still preserve the original types.
But it seems (as far as I know) that there's no way to pass directly a json stringified uri and then capture it with a json parsing.

My solution, till now, is to pass a value 'data' with json stringified object as value, containing all the parameters I want to get on server. Something like this:

(request to node.js)

$.post('server/test', {data: JSON.stringify({boo:true, str: 'true'})}).then( function (res) {              
    console.log (res.boo === true); //true
    console.log (res.str === 'true'); //true
});

(server side nodejs)

const express = require('express'), 
      bodyParser = require('body-parser'),
      app = express();
app.use( bodyParser.json() );
app.use( bodyParser.urlencoded({extended: true}) );

app.listen(8080);

app.post ('/server/test', async (req, res) => {    
    let {boo, str} = JSON.parse(req.body.data);  
    res.send({boo: boo, str: str});
});

(request to php)

$.post('includes/server.php', {
    data: JSON.stringify({boo: true, str: 'true'})
}).then( function (res) {    
    res = JSON.parse(res);         
    console.log (res.boo === true); //true
    console.log (res.str === 'true'); //true
});

(server side php)

$data = json_decode( $_POST["data"] );
$boo = $data->boo; $str = $data->str;
$res = (object) ["boo"=> $boo, "str"=> $str];
echo json_encode($res);

I wonder if someone knows a better (and simpler) solution to solve this issue, or if this is the best to preserve types on parameters.

  • `I don't know if there is something that I'm doing wrong`...no, that's just how it is. HTTP has no notion of data types, everything is just text. How you interpret the incoming data on the server side is up to you. Usually you need to parse it and check it matches the type you're expecting. With JSON, it does at least distinguish between strings and numbers and booleans. – ADyson May 26 '21 at 15:57
  • Why are you doing `{data: JSON.stringify({boo:true, str: 'true'})}` though? That's bizarre, you're putting JSON inside form-url-encoded data. Pick a data format and stick to it. If you want to send JSON then send actual JSON. Set the request's content type to application/json (https://stackoverflow.com/a/13204514/5947043) and then send just `JSON.stringify({boo:true, str: 'true'})`. In PHP there's a particular way to read that (from `php://input` - see https://stackoverflow.com/questions/18866571/receive-json-post-with-php) and I guess node will have no difficulty with it either. – ADyson May 26 '21 at 15:58
  • if I send only "JSON.stringify({boo:true, str: 'true'})", php doesn't recognize the type of values and the same for nodejs through BodyParser in express.js. I already set the content type to application/json and nothing changed. If you know the solution, please post a working code that still recognizes types without using 'data' parameter – Paolo Cirasa May 26 '21 at 16:36

1 Answers1

1

There is a difference between REQUEST & GET/URL, and from your code/example, I assume you are meaning GET/URL arguments, often referred to as URL query string.

It is good enough to assume there is no data type, or only STRING, for URL query values.

The same goes with PHP, more or less, there is no strict data type, unless otherwise you want to use the strict === operator.

So, basically, a pair of 'foo=true' is just a STRING to PHP when you get it via $_GET["foo"], not a BOOLEAN, however, evaluates to BOOLEAN TRUE when greater than 0 (zero).

That being said, the concept of preserving type over the URL query string doesn't apply, not only because the query string is not a compiler/interpreter, but also because of the size limitation. You cannot just go with JSON encoded string as query string because I assume that is subject to variable/unknown length, and with a very good chance that will exceed the length limit in the real world cases. Please also note that query string values are always decoded for URL encoding, thus might impact your JSON method adversly.

So, finally, to answer your question, as server side and client side are very clearly and intentionally screened to intercept each other and works in a REQUEST/RESPONSE model, you always know what is the expected data type on your server side, and convert it in your server side language if you need to.

If it is the case that you MUST deal it in some way that you are referring to as 'preserving the data type', I don't see any other quick option other than sending it over POST method.

Broken Arrow
  • 576
  • 3
  • 12
  • Ok. Let's say I already know the expected types, but if I have a bunch of parameters with several types, should I parse every single variable to its original type everytime I get a request? – Paolo Cirasa May 26 '21 at 16:41
  • For explicit cases, yes, which is very rare with PHP. If you send a value 'Foo=Bar' and use PHP, it will be STRING automatically; and for 'ID=997', PHP will allow you numeric actions without any conversion at all. For use with SQL, it is simply enough to know which is STRING or NUMERIC, and just quote around the STRING with single (or double) quotes. – Broken Arrow May 26 '21 at 20:04