JavaScript dictionary encoder for short text - javascript

I have the following JSON:
{"test": {"property 1": 345, "property 2": 976, "property 3": "asd"}}
I need to compress it to be very short, like that (in URL)
/#params=abs54sgdasd1we!ewd
I have a list of defined properties on that JSON, so that's why I'm asking what is the best dictionary encoder for JS. Later I should be able to decode from that string back to JSON.

You could just HTMLencode the whole JSON string. Remember that you need the key in "key": "value" pairs in the Object/"Associative array"/"dictionary", since ordering is not mandatory for that. Otherwise, 345|976|"asd" could end up as 976|"asd"|345 without the keys and have unexpected results. Otherwise, covert it to an Array/List so the order is maintained and you only rely on the order of values.
If "very short" is the main requirement and it must be in the URL, then store the JSON in a DB and generate an id or hash (like crc, md5) based on it as a lookup key which you can add to the URL parameters.
Edit: The property1,2,3 names can be reduced to a, b, c if you don't want to switch to an Array.
Edit2: If the application it will interact with is cookie aware, you could store the data in a cookie and the hash in the URL.
And, if the values of property 1-3 are limited, you could map them to predefined values of fixed length.

Related

How can I sort the order of key in a nested object in javascript?

the problem is:
I have a request with params like:
{ "foo": "bar", "bar": "baz", "baz" : { "nestedKey": "foo" } }
I need to sign it with Hmac512 algorithm, so I'll need to stringify the object first.
But, my concern is, if the order of the key isn't preserved, the signature generated by server and the client could be different.
to handle that, my idea is simply to order the keys of the object (including the keys nested inside that object).
how can I achieve this?
As stated in the OP, the input to the HMAC process must be deterministic.
But Javascript object elements' order cannot be set, no matter how much we'd like them to be settable. (I see this question re-occur every so often.)
Answer is to sort the the stringified string itself.
See json-stable-stringify for a solution.
Then feed the resulting string into the HMAC method. No need to base64 encode it.
You need to ensure that the message is the same in both sides, but you should not need to modify or adapt the message at all
Basically apply this algorithm
base64(sign(utf8(json message)))
Client side
Stringify: Convert the javascript object to string
UTF-8: Ensure you are using a known and fixed encoding like utf
Sign: Calculate HMAC over the resulting message
base64: Convert the binary signature to base64
Send to client the json message and the signature
Server side
Get the raw message from client and apply steps 2-4. Check if the signatures are equal

standard for representing arrays of integers in a url request

Is there a standard for handling an array of integers like the following:
http://localhost:3001/?tag_ids=7,10,45
or
http://localhost:3001/?tag_ids=[7,10,45]
I feel like I've written boiler-plate every 6 months and would much rather use some library.
A number of server-side scripting languages like PHP expect each value to be in a separate parameter, with the parameter name ending with [].
tag_ids[]=7&tag_ids[]=10&tag_ids[]=45
They recognize this syntax and collect all the values into an array. In PHP this would be $_GET['tag_ids'] = [7, 10, 45].
You can also optionally put strings inside the []; in this case, the server language will put them into its keyed data structure (associative array in PHP, dictionary in Python) with those as the keys.
You should call encodeURIComponent on tag_ids[], so they'll actually end up looking like tag_ids%5B%5D.

converting 'malformed' java json object to javascript

I have a Java JSON Object, its format is [{a=b}], I am trying to pass this object into javascript as a JSON object but its missing " on both the key and value as well as having "=" instead of ":"
Is there a simple way of converting this JAVA JSON object to be consumable by different services?
Parsing is proving to be very complicated as the actual JSON is nested and the lack of quotations and the lacking of indications for nestedness.
Sample of 'JSON' data:
[{wwnType=Virtual, serialNumberType=Virtual, connections=[], modified=2016-10-29T19:00:04.457Z, macType=Virtual, category=server-profile-templates, serverHardwareTypeUri=/rest/server-hardware-types/32006464-D3C6-4B4E-8328-47A193C6116C, bios={overriddenSettings=[], manageBios=false}, firmware={firmwareBaselineUri=null, manageFirmware=false, forceInstallFirmware=false, firmwareInstallType=null}, boot={manageBoot=true, order=[CD, Floppy, USB, HardDisk, PXE]}, hideUnusedFlexNics=true, bootMode=null, state=null, affinity=Bay, localStorage={controllers=[]}, type=ServerProfileTemplateV1, status=OK, description=, eTag=1477767604457/1, serverProfileDescription=test, name=test, created=2016-10-29T19:00:04.428Z, enclosureGroupUri=/rest/enclosure-groups/e989621b-930e-40e7-9db0-a6ddbf841709, uri=/rest/server-profile-templates/db1dbdcc-4237-4452-acc3-cf9dfdc75365, sanStorage={manageSanStorage=false, volumeAttachments=[]}}]
Thanks
It's not going to be simple. However, I think you can do this without writing a full-fledged parser, as long as you're willing to write a tokenizer, or lexical analyzer, to break your input string into tokens. The basic plan could be something like:
Convert your input into a list of tokens. I don't know what the format of your input is, so you'll need to do your own analysis. A token would be something like a single character [, ], {, }, comma, =; or an identifier (a or b in your example, but I don't know what the possible valid formats are); or, maybe, a string literal in quotes, or a numeric literal, depending on what your needs are.
Go through the string and replace the tokens you need to. Based on your example, I'd say that after a {: if the first token after that is an identifier, put it in quotes; if the second token after that is =, change it to :; if the third token after that is an identifier, put it in quotes. The same could be true after a comma, but you'll need to keep track of whether the comma is a separator for a list of key-value pairs in an object, or a list of values in an array. For that, you may need to keep a stack that you push whenever you see [ or {, and pop whenever you see } or ], so that you know whether you're inside an object or an array.
After you're done replacing everything, concatenate the tokens back together. The result should be a well-formed JSON object.
This is just a rough outline, since I really don't know all your requirements. You'll probably have to adapt this answer to meet your exact needs. But I hope this helps as a general idea of how you could approach the problem.
Sorry, I don't think there's a simpler answer, except that you might want to look into parser generators (see Yacc equivalent for Java). I haven't actually looked at any in Java, so I don't know how simple they are to use. Please don't try to solve the whole thing with regexes. (Regexes will be useful for breaking your string into tokens, but trying to do more than that with regexes is likely to produce nothing but migraine.)
I think isn't json object. json object should be like this.
Example:
JSONObject obj = new JSONObject();
obj.put("a", "b");
obj.put("name", "your name");
Output: {"a": "b", "name":"your name"}
Passing into javascript
var obj = '{"a": "b", "name":"your name"}',
var json = JSON.parse(obj);

Getting URL Parameters Based on a Template/Pattern

In order to perform AJAX calls, I extract URL values (embedded IDs and query string parameters) and store them in hidden inputs. Outside of this little bit of server-side work, I have a static HTML page.
I am looking for a library that can easily extract my URL values on the client-side. I'd like to specify the expected format (a URL template if you will): /account/{accountId}/edit?param={param}. Then I'd like the library to create an object based on the actual URL (based on window.location): /account/123/edit?param=234 and give me back an object: { accountId: 123, param: 234 }.
It would be nice if the library would allow me to indicate the expected type {accountId:int} so that the resulting object has a true, int, float, date, etc.
Does such a library exist for client-side JavaScript?

How to generate a JSON object dynamically with duplicate keys?

I know this will sound impossible but my boss told me I MUST send a JSON over an AJAX post call with jQuery that MUST HAVE DUPLICATE KEYS. the problem is that if I write something like this:
$.post("someurl", {
"key1" : "value1",
"key2" : "value2",
"key2" : "value3",
"key2" : "value4",
"key3" : "value5"
});
, jQuery will send the request as
someurl?key1=value1&key2=value4&key3=value5
all this because Javascript overwrites properties that have the same name. The JSON object is generated dynamically and I am NOT ALLOWED to use arrays in it. Can someone tell me how could I generate the JSON object dinamicaly and with duplicate keys?
I would realy appreciate any help from you!
From what I can see, {"a": "b", "a": "c"} actually is valid JSON according to RFC 4627.
An object structure is represented as a pair of curly brackets
surrounding zero or more name/value pairs (or members). A name is a
string. A single colon comes after each name, separating the name
from the value. A single comma separates a value from a following
name. The names within an object SHOULD be unique.
...where SHOULD means:
3. SHOULD. This word, or the adjective "RECOMMENDED", mean that there
may exist valid reasons in particular circumstances to ignore a
particular item, but the full implications must be understood and
carefully weighed before choosing a different course.
So yeah, basically you can do that, it is legal, but it's also a bad idea. Different JSON decoders will probably handle this situation differently and/or in undesiderable ways. Look at what the spec requires of parsers:
A JSON parser transforms a JSON text into another representation. A
JSON parser MUST accept all texts that conform to the JSON grammar.
A JSON parser MAY accept non-JSON forms or extensions.
An implementation may set limits on the size of texts that it
accepts. An implementation may set limits on the maximum depth of
nesting. An implementation may set limits on the range of numbers.
An implementation may set limits on the length and character contents
of strings.
...but an implementation doesn't have to handle situations like this sanely. For example:
# Python 2.7
>>> import json
>>> json.JSONDecoder().decode('{"a": "b", "a": "c"}')
`{u'a': u'c'}`
# Chrome 32
> JSON.parse('{"a": "b", "a": "c"}')
Object {a: "c"}
...and other implementations may legally give you (in Python notation):
{"a": "b"}
[("a", "b"), ("a", "c")]
[("a", ["b", "c"])]
[]
42
"your JSON is bad and you should feel bad"
...or just good old nasal daemons. Literally the only illegal thing for a JSON parser to do here is raise an exception.
The last thing you want to do in your production code is to rely on weird side cases. So the last thing you want to do is exercise your right to form nominally legal but practically useless JSON. If you want to do that, you'll have to do it by hand - build your own abstract syntax trees, your own parsers, your own generators, generators for anybody who might want to consume your data...
A Javascript object with duplicate keys is not a Javascript object. In fact, it is no more than a figment of your imagination. It is totally impossible.
The only way to do this is with an array:
{
"key1" : "value1",
"key2" : ["value2", "value3", "value4"],
"key3" : "value5"
}
jQuery will convert this into key1=value1&key2%5B%5D=value2&key2%5B%5D=value3&key2%5B%5D=value4&key3=value5
This is genuinely the only way to do this.* Is there a reason why your code cannot generate valid JSON?
* Except for writing your own parser that handles invalid JSON. But that would be breathtakingly stupid.
I would do it only if the JSON parser on the other side accepts it properly, without dropping anything. If you can show it dropping stuff, then you can look for another solution (like using an array, or generating the JSON by hand, or using a URL properly. You need better test cases first for your server.
If you can't change the source at the source, then change the source into something you can at least work with...
Parse the JSON into an Array of key value pairs (not into an object of key/value pairs).
You could do this easily if you have access to the JSON string, simply replace all "," with "},{" and wrap the result in "[" and "]".
You now have a valid JSON array of key/value pairs that is javascript legal.

Categories