How to read multi part form in node.js - javascript

I have a node.js application which currently supports only x-www-form-urlencoded requests. If someone needs to send a file as an attachment I have to extend the support for form-data. Reading the data from request is currently done using DecodeURIComponent and look similar to following. Is it possible to adapt this to read form data?
exports.parseUrlEncodedBody = function(event) {
//This is to extract url encoded data
var temp = {};
if (event.body) {
// retrieve keys & values
var pm = event.body.split("&");
// store keys and values in temp object
params.forEach(function (item, index, array) {
var keyValue = item.split("=");
var key, value;
if (keyValue.length >= 1) {
key = decodeURIComponent(keyValue[0]);
if (keyValue.length >=2) {
value = decodeURIComponent(keyValue[1]);
} else {
value = "";
}
temp[key] = value;
}
});
}

Is it possible to adapt this to read form data?
No. The data format is completely different. You would need to rewrite it from scratch.
Consider using a module such as multer which is designed for this.
If you want to write your own library from scratch, then you should consult RFC 7578, which describes the data format.

Related

How can I extract alternative names data from a CSR?

I have a CSR and I can parse all the data with pkijs.org lib, but I have no luck to parse alternative names data. How is it possible to do with a javascript? Some other libs can be in use, I guess, do you know one?
Following the docs of CertificationRequest class provided by pkijs here https://pkijs.org/docs/classes/CertificationRequest.html. We can see that the structure of a CSR. The subject alternative name will be stored in attributes propery of CertificationRequest object. But the structure inside of attributes is quite complex to make it as plain text. This is my code used to print out the subject alternative name
const pkijs = require('pkijs');
const utils = require("pvtsutils");
const asn1js = require("asn1js");
let base64 = "<your_csr_in_base64>"
let csrraw = utils.Convert.FromBase64(base64);
console.log(csrraw)
const pkcs10 = pkijs.CertificationRequest.fromBER(csrraw);
let seq = pkcs10.attributes[0].values[0];
let exts = pkijs.Extensions.fromBER(seq.toBER(false));
console.log(exts);
var san = getExtentionsForSANFromExtensions(exts);
console.log(san)
if (san != undefined) {
san.names.forEach(element => {
console.log(element.type + " = " + element.value)
});
}
function getExtentionsForSANFromExtensions(exts){
for (var i = 0 ; i< exts.extensions.length; i++) {
var ext = exts.extensions[i];
if(ext.extnID == '2.5.29.17') {
var octetString = asn1js.fromBER(ext.extnValue.toBER(false)).result;
return pkijs.GeneralNames.fromBER(octetString.getValue());
}
}
}
I've tested this code and it works properly with CSR generated by Keystore Explorer. Have not tested with another tool to generate CSR that supports subject alternative names.
Cheers!
If you have a CSR and need to extract the alternative names data from it, you can use the following command:
openssl req -in csr.pem -noout -text
This will print out the entire CSR, including the alternative names data.

How to read Java property file in AngularJS?

Is there any way to read a properties file from angularjs which resides outside the web server?
like in java the property file deployed out of the project but we can read those file in our project as filter.properties in this way any solution is there in angularJS.
I tried like this but getting undefined.
filter.properties:
key1=value1
key2=value2
sampleController.js
var app = angular.module('sampleApp', []);
app.controller('sampleController', function($scope, $http) {
$http.get('filter.properties').then(function (response) {
console.log('a is ', JSON.stringify(response.data.key1));
});
});
There are several ways to access properties files in angularjs.
Like every files properties file is a file with .properties extension.
Since java properties files are key value pair separated by = in a single line.
So we can convert a properties file into javascript object by iterating each lines in properties file and split-ing it with = symbol and storing it as javascript object which will help to access it quickly.
Here is its javascript implementation
function extractProperties(propertiesFileContents){
var keyValuePairs =propertiesFileContents.split("\n");
properties ={}
for (i = 0; i < keyValuePairs.length; i++) {
var keyValueArr=keyValuePairs[i].trim().split("=");
var key=keyValueArr[0];
var value=keyValueArr[1];
properties[key]=value
}
return properties;
}
Based on your code here iam adding a plunker here hope this may help you
Samuel J Mathew's solution works for me, but the properties file I have to deal with have multiple empty lines in the file, together with lines commented out, and sometimes with white spaces around the = sign. So I have to add some checks to handle these situations. The modified result is such, hopefully will be useful to those working with a more complex properties file:
function extractProperties(data){
const keyValuePairs = data.split("\n");
properties = {}
for (var i = 0; i < keyValuePairs.length; i++) {
const keyValuePair = keyValuePairs[i].trim();
if (!keyValuePair || keyValuePair[0] === '#') {
continue;
}
const keyValueArr = keyValuePair.split("=");
const key = keyValueArr[0].trim();
const value = keyValueArr[1].trim();
properties[key] = value
}
return properties;
}

How to extract information in a TSV file and save it in an array in JavaScript ?

I'm running into a problem. If I have only tsv's file name. How can i extract all its information and save it in an array, say X, where each row in the tsv file is represented by an array, say y, where X is an array of ys.
ALso how can i do this if i don't know the headers of columns names ?
You're going to need to use AJAX or just pure XMLHttpRequest.
http://d3js.org/ has a built-in tsv reader that does basically exactly what you want.
The syntax is
d3.tsv("file.tsv", function(data) {
// use data here
});
The data variable is an array of objects with key/value pairs where the first row in the file is read in as the keys. So, for example
Number Awesomeness
1 5
2 3
will return [{"Number":1, "Awesomeness":5}, {"Number":2, "Awesomeness":3}].
// get file contents, store in var str
var x = str.split('\n');
for (var i=0; i<x.length; i++) {
y = x[i].split('\t');
x[i] = y;
}
console.debug(x);
For help on how to get the file contents, you'll need to specify where these files will be located (on the client machine, server, etc.).
If the files are located on the client machine, you might have a rough road ahead of you.
If the files are located on the server, you'll need to do an AJAX request to get the file contents.
Sticking this here so I can find it next time I need it:
// parse_tsv(tsvstring, function (row) { do something with row })
function parse_tsv(s, f) {
var ix_end = 0;
for (var ix=0; ix<s.length; ix=ix_end+1) {
ix_end = s.indexOf('\n', ix);
if (ix_end == -1) {
ix_end = s.length;
}
var row = s.substring(ix, ix_end-1).split('\t');
f(row);
}
}
It's better than the accepted answer because it doesn't force building an array of lines in memory, but rather build little arrays one by one. In situations with large TSV, this can be helpful. Of course you could still build the array with the callback if that's what you need.
You don't have to use D3, JQuery or any another framework for this. Plain and simple JavaScript (AJAX technique):
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
var arrayWithValues = xhttp.responseText.trim().split('\t');
console.log(arrayWithValues);
};
};
xhttp.open("GET", "/some.tsv", true);
xhttp.send();
$result = array();
$fp = fopen('/path/to/file','r');
if (($headers = fgetcsv($fp, 0, "\t")) !== FALSE)
if ($headers)
while (($line = fgetcsv($fp, 0, "\t")) !== FALSE)
if ($line)
if (sizeof($line)==sizeof($headers))
$result[] = array_combine($headers,$line);
fclose($fp);
print_r($result);
You can do it with Alasql library:
alasql('SELECT MATRIX * FROM TSV("mydata.tsv")',[],function(res){
console.log(res);
});

Get Query String with Dojo

Users will be hitting up against a URL that contains a query string called inquirytype. For a number of reasons, I need to read in this query string with javascript (Dojo) and save its value to a variable. I've done a fair amount of research trying to find how to do this, and I've discovered a few possibilities, but none of them seem to actually read in a query string that isn't hard-coded somewhere in the script.
You can access parameters from the url using location.search without Dojo Can a javascript attribute value be determined by a manual url parameter?
function getUrlParams() {
var paramMap = {};
if (location.search.length == 0) {
return paramMap;
}
var parts = location.search.substring(1).split("&");
for (var i = 0; i < parts.length; i ++) {
var component = parts[i].split("=");
paramMap [decodeURIComponent(component[0])] = decodeURIComponent(component[1]);
}
return paramMap;
}
Then you could do the following to extract id from the url /hello.php?id=5&name=value
var params = getUrlParams();
var id = params['id']; // or params.id
Dojo provides http://dojotoolkit.org/reference-guide/dojo/queryToObject.html which is a bit smarter than my simple implementation and creates arrays out of duplicated keys.
var uri = "http://some.server.org/somecontext/?foo=bar&foo=bar2&bit=byte";
var query = uri.substring(uri.indexOf("?") + 1, uri.length);
var queryObject = dojo.queryToObject(query);
//The structure of queryObject will be:
// {
// foo: ["bar", "bar2],
// bit: "byte"
// }
In new dojo it's accessed with io-query:
require([
"dojo/io-query",
], function (ioQuery) {
GET = ioQuery.queryToObject(decodeURIComponent(dojo.doc.location.search.slice(1)));
console.log(GET.id);
});
Since dojo 0.9, there is a better option, queryToObject.
dojo.queryToObject(query)
See this similar question with what I think is a cleaner answer.

jQuery deserialize form

I am using jQuery Serialize to serialize my form elements and would like to deserialize them back. Unfortunately can't find any working jQuery deserializer, any suggestions?
I wrote a version of jQuery.deserialize that supports serialized data generated from the serialize, serializeArray and serializeObject functions. It also supports all form element types, including checkboxes and radio buttons.
Try this:
function deparam(query) {
var pairs, i, keyValuePair, key, value, map = {};
// remove leading question mark if its there
if (query.slice(0, 1) === '?') {
query = query.slice(1);
}
if (query !== '') {
pairs = query.split('&');
for (i = 0; i < pairs.length; i += 1) {
keyValuePair = pairs[i].split('=');
key = decodeURIComponent(keyValuePair[0]);
value = (keyValuePair.length > 1) ? decodeURIComponent(keyValuePair[1]) : undefined;
map[key] = value;
}
}
return map;
}
I was very interested in trying JQuery.deserialize, but it didn't seem to handle checkboxes at all, so it didn't serve my purposes. So I wrote my own. It turned out to be easier than I thought, because the jQuery val() function does most of the work:
jQuery.fn.deserialize = function (data) {
var f = this,
map = {},
find = function (selector) { return f.is("form") ? f.find(selector) : f.filter(selector); };
//Get map of values
jQuery.each(data.split("&"), function () {
var nv = this.split("="),
n = decodeURIComponent(nv[0]),
v = nv.length > 1 ? decodeURIComponent(nv[1]) : null;
if (!(n in map)) {
map[n] = [];
}
map[n].push(v);
})
//Set values for all form elements in the data
jQuery.each(map, function (n, v) {
find("[name='" + n + "']").val(v);
})
//Clear all form elements not in form data
find("input:text,select,textarea").each(function () {
if (!(jQuery(this).attr("name") in map)) {
jQuery(this).val("");
}
})
find("input:checkbox:checked,input:radio:checked").each(function () {
if (!(jQuery(this).attr("name") in map)) {
this.checked = false;
}
})
return this;
};
You should be able to use this like this:
$("#myform").deserialize(data);
Where data is a parameter list such as what $("#myform").serialize() would produce.
It affects all fields in the form, and it will clear the values of fields that are not contained in the data. But you can also pass any selector to affect only specific fields, as you can with the serialize function. E.g.:
$("select").deserialize(data);
Half of jQuery Serialize is param(), so half of something that deserializes a query string is going to be a deparam. Unfortunately I haven't been able to find a good standalone deparam. For now I recommend getting the jQuery BBQ library and using that. If you don't need the other stuff you can remove them. I read somewhere that Ben Alman (cowboy) planned to extract deparam into its own module.
For the rest of deserializing, you'll just need to loop through the object that deparam returns and for each key and value pair in the object, select the form element based on the key, and set the form elements value to the value.
Bit late on this one, but somebody might find this useful.
function fetchInput(identifier) {
var form_data = identifier.serialize().split('&');
var input = {};
$.each(form_data, function(key, value) {
var data = value.split('=');
input[data[0]] = decodeURIComponent(data[1]);
});
return input;
}
I'm not now answering your question but my guess is that you want to serialize it and send back to server and then use the serialized data which is why you have to deserialize it?
If that's the case you should consider using .serializeArray(). You can send it as POST data in ajax, and then access later as well because you will have object.
May be a bit late, but perhaps you are looking for something like JQuery.deserialize. Problems: no support for checkboxes or radio buttons.
Using Jack Allan's deparam function with jQuery, you can change this line:
map[key] = value;
to
$('input[name=' + key + ']').val(value);
Which will load the data back into your form fields.
this code returns an array when same key is spotted multiple times in the serialized string
chaine="single=Single1&multiple=Multiple&multiple=Multiple1&multiple=Multiple2&multiple=Multiple3&check=check2&radio=radio1"
function deserialize(txt){
myjson={}
tabparams=chaine.split('&')
var i=-1;
while (tabparams[++i]){
tabitems=tabparams[i].split('=')
if( myjson[decodeURIComponent(tabitems[0])] !== undefined ){
if( myjson[decodeURIComponent(tabitems[0])] instanceof Array ){
myjson[decodeURIComponent(tabitems[0])].push(decodeURIComponent(tabitems[1]))
}
else{
myjson[decodeURIComponent(tabitems[0])]= [myjson[decodeURIComponent(tabitems[0])],decodeURIComponent(tabitems[1])]
}
}
else{
myjson[decodeURIComponent(tabitems[0])]=decodeURIComponent(tabitems[1]);
}
}
return myjson;
}
Needed all in a single string, which can be stored in maybe COOKIE, and later read and fill the same form with input values.
Input elements seperator: ~ (use any seperator)
Input attributes seperator: | (use any seperator)
input type | input name | input value ~ input2 type | input2 name | input2 value
var formData = '';
$('#form_id').find('input, textarea, select').each(function(i, field) {
formData += field.type+'|'+field.name+'|'+field.value+'~';
});
Example:
hidden|vote_id|10~radio|option_id|~radio|option_id|427~radio|option_id|428~
If what you want is to remove the standard URL-encoded notation, you can use JavaScript's decodeURIComponent(), which will give you a regular string, just like this:
var decodedString = decodeURIComponent("Http%3A%2F%2FHello%3AWorld");
alert(decodedString);
In this case, decodedString will look like Http://Hello:World, here's a working fiddle.
Got all of this searching for this same issue, and found the answer here: How can I decode a URL with jQuery?
I know this is an old question, but doing some searches for jQuery deserialize got me here, so I might as well try to give a different approach on the issue for people with the same problem.

Categories