Best Practice for using Form Data in a http request - javascript

We have a previous implementation whereby we send one key value pair in the form data to the server
ie. message=something_blah
Is there any point in actually having this in form data? Should form data only be used if we are building an object or array of object?
If we only have one key value pair would it not be better to insert it as part of the query request parameter?

Form parameters and query parameters are accessed, more or less, from the same place from within a servlet.
For example, in doGet() (doPost() would've gone the same way, so would all the other http methods)
public void doGet(HttpServletRequest request, HttpServletResponse response) {
String message = request.getParameter("message"); // would return something_blah or null if no parameter
...
}
To answer your question in the OP comments, parameters coming from request.getParameter() are Strings. You can then convert them to other types (parse to numerical value) or use them to initialize Class instances. Their use is up to you.
This parameter could have come from
<form method="get">
<input name="message" type="text" value="something_blah"/>
</form>
or from the url
http://www.yourdns.com/myapp?message=something_blah
To answer Should form data only be used if we are building an object or array of object?, some frameworks like Spring use parameters coming from html forms (and query string) to automatically instantiate objects for you using reflection and some naming conventions. This is not necessary, it's just useful. So review your requirements and see if you need it.

Related

converting value from input tag to array

I was wondering if there is a way to store pass an array to an input tag's value attribute? So if I have a form.
<form action="/some-route" method="POST">
<input type=hidden name=someProperty />
<button type="submitt">send</button>
</form>
So with a hidden input tag with name equal to someProperty is there a way to store an Array of data inside the value property? Basically when I submitt the form I want the value of the input tag post the data in the form of an array.
I have read somewhere that I can do this by setting the value of someProperty to name=someProptery[]. However I think this may only work in PHP.
With HTTP there are basically no data types, including array. When you send a request or response via HTTP the data are just basic text. But how is it possible that some languages like JavaScript or PHP give us the data in easy to use variables? That is because we use something called media type.
Media type
Media types (or MIME) are basically different formats/representations of data. After all all the data we send are basically just bytes (or we might see as a text). MIME universaly describes how data are structured so when one programmer sends some data to other programmer they will both know how to properly parse it. Take for example JSON. JSON is simple media type where we represent our data with specific syntax in which we use concepts like objects, arrays, int or strings. JSON is generally recognized in many languges so you might send data with JavaScript and parse it with PHP, because they both know how the JSON is structured and they will parse into its own structure (like yours PHP array).
Sending data with HTML forms
When we submit a HTML form its data are by default sent as application/x-www-form-urlencoded media type (if you inspect the raw HTTP request you can see it for yourself). This media type is much more simpler than JSON because it only contains keys and values. For example name=Bob&message=hello contains two keys: name and message. name holds value Bob and message holds hello. And you see why this might be a problem when you want to send an array with this media type.
Solution
You wrote a solution that works only for PHP and you are right. PHP can translate keys that end with [] to an array. So if you have data arr[]=first&arr[]=second PHP will parse into array ["first", "second"] stored under arr as its name. But there is no specification that says this is the correct way of parsing application/x-www-form-urlencoded. Every language might parse into a bit different structure. So the solution? It depends on the server side. Altough some languages can't interpret the [] notation into an array like PHP do, you can write your own parser which can parse it into an array (or you might find library for it). Or if you can just put values into a input and seperate with some character like ; and when the input is recieved on the server you just split the accepted value into multiple values and you got your array! Or you can even put a JSON into some of your inputs and parse JSON instead. The solution is really up to you.
Form inputs can only contain string values, not arbitrary javascript constructs.
HTML does support multiple form inputs of the same name, and will pass all of the individual values to the server as separate params (with the same name) which could then be parsed back into an array on the server. For example, this form would end up calling the URL http(s)://example.com?foo=1&foo=2&foo=3:
<form method=GET>
<input name="foo" type="hidden" value="1">
<input name="foo" type="hidden" value="2">
<input name="foo" type="hidden" value="3">
<input type="submit">
</form>
PHP uses the convention that if the input name includes [] then it will automatically parse the results into an array for you; that is specific to PHP however, the brackets have no meaning otherwise. If you are using some other serverside language (or using the data clientside) then you would need to read each of the values individually yourself and combine them into an array. In some cases it may be simpler to convert your array into a string form, CSV or JSON perhaps, and stuff that into a single input.

java pass string web request to non string #RequestParam

I am working on a react application that has a java backend. The react frontend sends a URL request to a java web service controller, and within that webservice controller, the variable types are defined. Since a URL request is a string I’m having trouble dealing with non-string values. And since Javascript is not a strongly-typed language like Java I cannot definie variable types on the front end.
Web Request Example:
localhost:8080/filteredCSV.json?status=UNDER_ACTIVE_REVIEW,AUTHORIZED_BY_DWB,UNDER_CONSTRUCTION,CONSTRUCTION_COMPLETED&engineerEmail=null&issues=null&date=null
Web Service Controller:
#RequestMapping(value = "/filteredCSV.json")
#ResponseBody
public WebserviceResponse<?>filteredCSV(
#RequestParam(value="status") ArrayList status,
#RequestParam(value="engineerEmail") ArrayList engineerEmail,
#RequestParam(value="issues", required=false) Boolean issues,
#RequestParam(value="date", required=false) Local Date date){
return service.filteredCSV(status, engineerEmail, issues, date);
}
If the Boolean or Date values are null, then null is getting passed as a string which causes a TypeMismatch Error and the program stops. I do not appear to have a way to change the string to to a non-string null value once it hits the web service controller. I understand why this is occurring, but I am not sure if there is a way to work around it so that I can pass null as a value and not null as a string. Am I just screwed? Is there not a way to deal with this?
You're not sending null as a value, you're sending a string that contains the word 'null.
Send no value "" instead of the string value 'null'. This is what the #RequestParameter is expecting when it should be ignoring a parameter.
#RequestParameter docs
If you can't edit the javascript you still have some options ... what spring is really doing there is data binding values from the http request to instances of Java variables. You can override or bypass this as you need. (This sort of approach is the 'old' way of doing this and the very problem spring annotations hope to solve).
#RequestMapping(value = "/filteredCSV.json")
#ResponseBody
public WebserviceResponse<?>filteredCSV(HttpRequest request){
String date = request.getParameter('date');
// Convert date if not 'null' here, and so on
}
I like the suggestion posted by #zmf, However If want find other work arounds. Please refer some of the approaches I think will work:
Solution 1: You can introduce a filter, and parse all the request parameters as string. When you encounter null as string do not send the param further, it will be considered as null at controller level.
Solution 2: Replace RequestParam type like Date, Boolean with String. You can then process accordingly.

Getting string index value from Javascript to MVC C# Controller using string[] array as a parameter

I am new in this environment and i just want to ask somebody if it is possible to get the string value not the index value using string[] array as a parameter?
Below are those images: ajax pass this data into controller
I am using ajax to pass my data in to the url controller in c# mvc.
By the way, here's my sample array data: prepared data..
the highlighted one is my array and in my parameter in mvc # is declared as string [] methodParam: highlighted parameter,
Those not highlighted parameter are working. all i want to do is getting one by one string in methodParam. i tried to use this
GetMethodParam.IndexOf("Date").ToString() but the output is -1 which probably not available in context.
i just want to get each string and its value because i send it to the email outlook..
like this. enter image description here.
Any Suggestions, clarification or comments is highly appreciated. Thank you ;) .
You don't need the individual input in data on ajax call, just use the last one UserHeader
and in Acton(C#) use a model as argument with containing all attributes of UserHeader.
Or, remove UserHeader from data and Use each attributes as individual argument in C# Action with same name.

Dynamic search input as variable for cypher

I'm trying to create an result page with structr 2.0.1.
enter image description here
Within these page I want to show the results of the user input. The string typed into my input field should be transferred via cypher query to my Neo4j-DB.
Input = "admin" -> Cypher(Match (n) Where n.name = 'admin' Return n)
The return value will be used to instantiate a graph obj via an integer-id (that works totally fine and is no issue).
After hours of investigating unfortunately I'm not able to do it witch the built-in functionality. I tried a lot with the "Query & Data Binding", & "HTML-Properties"-Page and Java Script as well but I couldn't transfer the value from my html element to my cypher query function within my fronted.
[input field ("String")--> button fuction()--> cypher (Query) --> function input {graph.addNode(ID)}]
There must be a solution within structr to solve this problem without a direct ajax-call.
Maybe someone of you discovered the same problem or has a solution for this.
I would very appreciate some help in this case.
Thanks!
Maze
the value of your request parameter is available in StructrScript, see https://support.structr.com/article/119 for more details on that.
In the scripting context, there is an object named request that you can access directly, which will contain any request parameter you send to Structr. So in your case, you can access the value of your input field (provided that you set the name to name) like this:
${request.name}
The following steps are needed to make that work:
create <form method="POST" action="/${page.name}">
insert <input type="text" name="name" value="${request.name}">
insert <input type="submit" value="submit">
When you submit the form, the request parameter "name" will be available in the Structr context as described above.
To insert that value into a Cypher query, you have to construct the query around the request value, for example like that:
${cypher(concat('MATCH (n) WHERE n.name = "', request.name, '" RETURN n'))}
But be very careful with a setup like that, because the above code is vulnerable to a query injection attack (aka SQL injection, or rather CQL injection in this case).

NewtonSoft JSON converter serializes but does it weirdly. How to fix?

Given the following object
Friend Class GetLocationsResult
Public Property X1 As String
Public Property X2 As String
Public Property X3 As String
Public Property X4 As String
Public Property X5 As String
Public Property X6 As Double
Public Property X7 As Double
End Class
And it is declared and instantiated thusly:
Dim objList as List(of GetLocationsResults) = new List(of GetLocationsResults)
And objList is populated via an iterator that churns through a collection of objects/aggregate classes. The iterator just shoves values into a new GetLocationsResult object and then adds it to the list.
And given the NewtonSoft JSONConvert.SerializeObject(objList) results:
{"d":"[{\"X1\":\"Store Name\",\"X2\":\"Address\",\"X3\":\"City\",\"X4\":\"State\",\"X5\":\"Zip\",\"X6\":Coord1,\"X7\":Coord2}]"}
This point has been addressed and is no longer an issue
There are several issues with this result set. First, for whatever odd
reason, the object being named "d" is not acceptable.
How can I specify something other than "d" for the "name" of the json array?
When I attempt to JSON.parse the response, it needs to be in the following format in order to actually get to the data:
resultSet = JSON.parse(data.d);
console.warn(resultSet[0].X1);
Having to say resultSet[0] is, of course, not acceptable.
How do I cause the 'JSONConvert.Serialize' method to not wrap the response in such a way that I have to refer to the first index of the
resulting JSON data so that I can say resultSet.X1 instead of
resultSet[0].X1?
As requested, here is some more detailed information that may be relevant to the issue at hand.
The data is being returned from a WCF service. The exposed method is decorated thusly:
<WebInvoke(Method:="GET", ResponseFormat:=WebMessageFormat.Json)>
and returns type String. The service is being consumed by a desktop application and a mobile platform. The desktop website can have its own method and, in fact, does because we don't want to deal with X1, X2, etc while the mobile platform devs have declared that as necessary. As noted, the method returns a number of results in the form of a custom, aggregate class which is then shoved into a class object which is only a collection of properties. The return statement is thus:
Return JsonConvert.SerializeObject(retVal)
where retVal is a List(of GetLocationsResult)
So while having to access the data via index may be fine for the website, it is not acceptable for the mobile platform. Because each will run their own methods, it is possible to have a unique solution for both if needed.
Three things.
It sounds like you're returning that back through an ASP.NET ASMX
ScriptService or ASPX [WebMethod]. When using one of those
endpoints, you don't need to (and shouldn't) manually serialize the
object into JSON. ASP.NET will do that for you automatically. You don't need to use JSONConvert at all; just return your object as the result. That's why you're seeing all that escaped data after the .d. It's JSON serialized twice.
As WhiteHat mentioned, the .d is a good thing in some situations. It's introduced by default in these ASP.NET JSON services and can't easily be removed on the server-side, but is easy to account for when you parse the response on the client-side.
You are returning a List(of GetLocationResults), which maps to a JavaScript array. That's why you need to use resultSet[0].X1 to access a value in the result. If you want to access that value via resultSet.X1, you need to be sure to return only a single GetLocationResults object instead of a List of them.
Does that help? If you could update your question with a more complete example of your server-side and client-side code, I could give you an example of how to address the preceding three issues.

Categories

Resources