Error while getting parameters from request object containing `&` character - node.js

I'm trying to get param from request object using following code.
module.exports = function (req, res) {
var query = req.query;
var data = JSON.parse(query.param1);
}
This is working fine for most of the cases.
If param1 contains & character then query.param1 get values before & and next values are considered as new param.
eg
localhost/?param1={"url":"http://s.test.com/x?format=jsonp&id=a&callback=b"}
Edit original url is already encoded
localhost/?param1=%7B%22url%22%3A%22http%3A%2F%2Fs.test.com%2Fx%3Fformat%3Djsonp%26id%3Da%26callback%3Db%22%7D
in this case I'm getting param1 = {"url":"http://s.test.com/x?format=jsonp
which is not valid json, so I'm getting error, currently we've solved it using regex (removing localhost/?param1= part of url).
What's best way to handle this use case?
Edit : server environment
centos 6.5 server
node v0.12.7
express#4.13.3

req.query is already an object with express :
An object containing a property for each query string parameter in the route. If there is no query string, it is the empty object, {}.
req.query documentation

You have to encode your URL before calling nodejs API. And on the nodejs side, you have to decode the URL to get correct parameteres.

Related

Angular 7.x query to node express server is converted to an object array of characters

I am sending a query string to a node express server. When I access the req.query property it is an array of characters instead of a normal object or the string I sent. Any Ideas?
Query sent
const data = await this.cspCrudService.findOne(stringQuery);
service
findAll(params: any): Promise<T[]> {
THIS LINE BELOW WAS THE PROBLEM
const query = StringUtil.toMongoQueryString(params);
return this.httpClient.get<T[]>(`${this.url}${this.endpoint}/${query}`).toPromise();
}
"location[$regex]=^F&location[$options]=i"
req.query
{"0":"l","1":"o","2":"c","3":"a","4":"t","5":"i","6":"o","7":"n","8":"[","9":"$","10":"r","11":"e","12":"g","13":"e","14":"x","15":"]","16":"=","17":"^","18":"F","19":"","20":"l","21":"o","22":"c","23":"a","24":"t","25":"i","26":"o","27":"n","28":"[","29":"$","30":"o","31":"p","32":"t","33":"i","34":"o","35":"n","36":"s","37":"]","38":"=","39":"i"}
I added a "StringUtil.toMongoQueryString" function some time ago for testing and forgot it was there. After removing it all worked as expected.

how to pass pathParam, queryParam and headers in one GET request when url is String variable

First question:
I have a API GET request which contains path parameters, query parameters and headers, and I'd like to put my request url as a string variable, how can I achieve it?
Second quesiton:
How to pass pathParams to a string variable?
I've studied how to pass path parameters, but all examples get("http://some_url/{path}"), I'd like to put the url as a String.
like String url = "http://my/request/url",
how to get with url+{id}? not get the http string?
given()
.contentType(ContentTypeJSON).
with()
.pathParams("id", "1").
when()
.get("http://my/request/url/{id}").
then()
.assertThat().
.statusLine("HTTP/1.1 200 OK");
Simple way to avoid rework is using the below code .
/*
* We can parameterize it using baseURI and basePath and send a request to get a customer using ID
*/
RestAssured.baseURI = "http://parabank.parasoft.com/";
RestAssured.basePath = "parabank/services/bank/customers";
//also we can use a path parameter for the same request
given().contentType(ContentType.JSON).pathParam("customers", "12212").when().get("{customers}/").then().statusCode(200).log().all();

Node Express - How to support encoded url query string

Using node v6.2.0, express 4.14.0.
When entering site url as: 'http://site.name/?key=value', I'm able to get the query value by:
app.get('/', function (req, res) {
// req.query.key equals 'value'
});
But when entering encoded url: 'http://site.name/?key%3Dvalue', the req.query object looks like this:
{ 'key%3Dvalue' : '' }
Is there a way to make node req.query to parse the url correctly?
If no, what is the preferred method to extract this query value?
As understood from the comments, the parsing is correct and it shouldn't decode %3D to key delimiter.
In this case there was already clients in the wild that tried to reach the address in encoded url (because of client bug).
so I've added a temporary handler on the server to parse the '%3D' as '='.
const value = req.query.key ||
url.parse(req.url.replace('%3D', '='), true).query.key;
When the clients will rollout a new version with a fix, I could remove this handler from the server and use only req.query.key as it should be.

NodeJS Express encodes the URL - how to decode

I'm using NodeJS with Express, and when I use foreign characters in the URL, they automatically get encoded.
How do I decode it back to the original string?
Before calling NodeJS, I escape characters.
So the string: אובמה
Becomes %u05D0%u05D5%u05D1%u05DE%u05D4
The entire URL now looks like: http://localhost:32323/?query=%u05D0%u05D5%u05D1%u05DE%u05D4
Now in my NodeJS, I get the escaped string %u05D0%u05D5%u05D1%u05DE%u05D4.
This is the relevant code:
var url_parts = url.parse(req.url, true);
var params = url_parts.query;
var query = params.query; // '%u05D0%u05D5%u05D1%u05DE%u05D4'
I've tried url and querystring libraries but nothing seems to fit my case.
querystring.unescape(query); // still '%u05D0%u05D5%u05D1%u05DE%u05D4'
Update 16/03/18
escape and unescape are deprecated.
Use:
encodeURIComponent('אובמה') // %D7%90%D7%95%D7%91%D7%9E%D7%94
decodeURIComponent('%D7%90%D7%95%D7%91%D7%9E%D7%94') // אובמה
Old answer
unescape('%u05D0%u05D5%u05D1%u05DE%u05D4') gives "אובמה"
Try:
var querystring = unescape(query);
You should use decodeURI() and encodeURI() to encode/decode a URL with foreign characters.
Usage:
var query = 'http://google.com';
query = encodeURI(query);
query = decodeURI(query); // http://google.com
Reference on MDN:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI
Decoding query parameters from a URL
decodeURIComponent cannot be used directly to parse query parameters from a URL. It needs a bit of preparation.
function decodeQueryParam(p) {
return decodeURIComponent(p.replace(/\+/g, ' '));
}
console.log(decodeQueryParam('search+query%20%28correct%29'));
// 'search query (correct)'
SOURCE: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#decoding_query_parameters_from_a_url
#**update may-2020**
# how to use an encoder/decoder on node js
### I am writing my answer due to I have noisy data I spend 4 hour to fixed
data email input = myemail#gmail.com
data URL input = /us/home
```
decodeURI function that only decodes a URL special character
email output =>myemail%40gmail.com
url output => %2Fus%2F
using decodeURIComponent
email output = > myemail#gmail.com
url output => /us/
```
here some clarification where you can use decodeURI and decodeURIComponent a fucntion

Breeze Json uriBuilder

I'm trying to use breeze.js with sails.js.
Therefore I'm using the breeze json uriBuilder.
I logged the req.query and got the following:
{ '{"where":{"name":"foo"},"orderBy":': { '"name"': '' } }
To query waterline objects I need to bring it into a format like this:
{ where: { name: 'foo' }, sort: 'name' }
First thing I tried:
var queryString = JSON.parse(Object.keys(req.query)[0]);
That works as long as I only put a where clause in. But with more parameters i get this strangely formatted json object.
How can I parse it to get the correct object?
Solution:
Don't parse he req.query. Parse the url and parse it. This way u will get a json uery that sails accepts. Now strip of unsupported parameters as select and you're done.
var parsedUrl = urlUtils.parse(req.url, true);
var jsonQueryString = Object.keys(parsedUrl.query)[0];
var jsonQuery = JSON.parse(jsonQueryString);
Good question! We haven't yet documented this adequately, but the basic idea is that there is a breeze-client npm package (https://www.npmjs.com/package/breeze-client) that you can use to parse the incoming json query into a breeze EntityQuery instance, from there you can interrogate the EntityQuery and turn it into whatever server side syntax you want, i.e. in your case Sails.)
// req = the HTTP request object.
var resourceName = req.params.slug; // the HTTP endpoint
var entityQuery = breeze.EntityQuery.fromUrl(req.url, resourceName);
// you would write the transform to sails below.
var sailsQuery = tranformToSails(entityQuery);
This is exactly what we do in the breeze-sequelize npm package where we take the incoming req.query and go thru the process above to create a 'Sequelize' query.
See http://www.getbreezenow.com/sequelize-mysqlpostgressql-lite

Resources