leora
leora

Reputation: 196449

Why do I have to encode a string when reading and writing form inputs using jquery?

I am programatically reading data from a text input using standard Jquery like this:

  var listName = $('#list').val();

and then I am adding a hidden input field into a form before submitting like this:

var myForm = $("#myForm);
myForm.append('<input type="hidden" name="List" value="' + listName + '" />');

In one example, the value in the field is:

Key Date & Times

so on the UI it looks like this

<input type="hidden" name="MyList" value="Key Date & Times" />

when I submit the form using:

var myForm = $("#myForm);
myForm.submit();

and check it on the asp.net-mvc server side i only see:

Key Date 

being sent over. After some research, it was suggested to write some javascript to run the value through:

encodeURIComponent()

After doing that and taking a look at the server side, I now see:

Key%20Date%20%26%20Times

How can I convert that back to

Key Date & Times

on the C# asp.net-mvc server side? Or Seperately, if I am doing something wrong on the client side, please let me if you have any suggestions.

My main question is why do i have to worry about encoding the value of a hidden input box in a form. I would have thought this would be taken care of for you.

Upvotes: 16

Views: 3523

Answers (12)

Abhirath Mahipal
Abhirath Mahipal

Reputation: 956

I had the same problem 3 to 4 days back. I was working with Angular and ASP. Like the answers above state I too had to use URLDecode.

Answering your question:- Why should I encode user input?


Avoid Unexpected Behaviour

Say your application can handle two parameters in a GET request.

This only takes in one argument
localhost:5000/stalls?searchbook=

This takes in two arguments
localhost:5000/stalls?searchbook=&includesecret=

You also have a page that can search for books.
Whatever the user types into the search bar results in a GET request.
localhost:5000/stalls?searchbook=USERSTRINGGOESHERE

If the user were to search for &includesecret=true
Resultant GET Request localhost:5000/stalls?searchbook=&includesecret=true and might accidentally result in private data being leaked to the user on the results page.

Symbols that are normally encoded (spaces, &, % etc) can many a times mean different things. '&' separates keys in a GET request and can also be a part of a string, so using it without encoding can result in expected behaviour.

P.S:- Private data shouldn't be queried via a GET request. It's just for the sake of this example :)


Consistency

While testing my application I noticed that PhantomJS encoded strings by default. This way I got different search results in different clients. It is therefore safe to assume that some clients might encode the URL even if you don't do it.


Another Example

'#' keys can be a part of a URL. If I visit localhost:5000/homepage.html#footer the element with the ID footer comes into display. This too can cause lead to behaviour that you do not expect. Try entering # in a GET request parameters that isn't encoded nor is cleaned of non alphabetic characters and you'll most likely end up in a situation similar to mine. The search functionality that I wrote a few days back would break if I entered # in it (when it wasn't encoded).

Upvotes: 0

Ciro Corvino
Ciro Corvino

Reputation: 2128

It is very likely you are submitting a GET request to the server, and therefore all values of each input form fields are posted to the server in the query string.

In this way, as already said by Zulqarnain Jalil, every '&' it is interpreted by the server as a separator of the key/value pairs in the query string, and so you miss the last part of your "List" hidden input form field.

Hence, in this case you have to url-encode all your values with "&" char.

Instead, if you submit a POST request to the server, you needn't to do any url-encoding of form field values, because they are passed to the server separately, namely not in the same string.

If you want to avoid url-encoding try to transform your request in a POST request:

var myForm = $("#myForm");
myForm.method = "post";
myForm.submit();

Upvotes: 2

I think no need to do any thing with your code, it works properly, i have folow below code, please confirm it.

View/Html:

@using (@Html.BeginForm("Save", "Home", FormMethod.Post, new { id = "myForm", name = "myForm" }))
{
    <input type="button" class="btn btn-danger" value="Click" id="btnClick">
}

Jquery:

$(document).ready(function () {
    var myForm = $("#myForm");
    myForm.append('<input type="hidden" name="List" value="Key Date & Times" />');

    $('#btnClick').click(function () {
        var myForm = $("#myForm");
        myForm.submit();

    });
});

Controller:

public ActionResult Save()
{
      return RedirectToAction("Index");
}

Output:

enter image description here

Upvotes: 2

Juan G Carmona
Juan G Carmona

Reputation: 2208

you said your main question is:

why do i have to worry about encoding the value of a hidden input box in a form. I would have thought this would be taken care of for you.

Well, the answer is because otherwise it could lead to injection problems. (Also, hidden fields are not the place for storing sensitive information and I wonder why that input is hidden, also, to be hidden won't change how it behaves...)

In order to fix your issue you could mix htmlEscape and string replace functions, like in the answer to this question (Encode hidden form field value)

function htmlEscape(str) {
    return String(str)
        .replace(/&/g, '%26')
        .replace(/ /g, '%20');
}

I hope it helps.

Upvotes: -1

Niraj
Niraj

Reputation: 793

You can simply add accept-charset="ISO-8859-1" in form tag and don't worry about encoding it automatically converts special characters.

<!DOCTYPE html>
<html>
<body>

<form action="demo_form.asp" accept-charset="ISO-8859-1">
  First name: <input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
  <input type="submit" value="Submit">
</form>

</body>
</html>

You can test it here

Upvotes: 0

Shahbaaz
Shahbaaz

Reputation: 421

You can replace all the %20 with spaces.

string values = "Key%20Date%20%26%20Times"; string decodeString = values.replace(/%20/g,' ');

Upvotes: -1

Hamza Ahmed
Hamza Ahmed

Reputation: 1791

Your main question encoding the value of a hidden input box in a form can be answered like this and this is just not pertaining to hidden inputs it relates to any data being posted to the server.

When data contains spaces and special characters like (&) in your case then it is the responsibility of the application developer to encode it so that the data is safe to be processed by the server. Having spaces and special characters pose security issues like XSS. This is just one of the many steps a responsible developer should take to mitigate such security threats.

Regarding how to get back the values at the server side use the following class found in System.Web namespace

string values = "Key%20Date%20%26%20Times";
string decodeString = HttpUtility.UrlDecode(values);

Hope it answers your question(s)

Upvotes: 0

Amirhossein Mehrvarzi
Amirhossein Mehrvarzi

Reputation: 18944

There's something wrong on client-side. I've tested the following code which is like one you wrote and worked fine!

<input type="hidden" id="ref" value="Key Date & Times" />
<form id="form1" action="~/home/handle" method="post">
    <input type="submit" />
</form>

<script>
    var myForm = $('#form1');
    var listName = $('#ref').val();
    myForm.append('<input type="hidden" name="name" value="' + listName + '" />');
</script>

You have no need to use conversion tools!

Upvotes: 2

Zulqarnain Jalil
Zulqarnain Jalil

Reputation: 1681

this happens when you use GET method to submit a form (in GET method '&' acts as a variable separator) you have to use POST method or String manipulation.

if you are using encodeURIComponent() you can convert it back using Server.UrlDecode(""); on server side

you can also read this for extra knowledge Click here

Upvotes: 2

Charles Owen
Charles Owen

Reputation: 2838

A lot of this has to do with implementing security against Cross Site Scripting attacks (XSS). You need to encode all html input fields that will be used in the post request. Otherwise someone could add domaliciousStuff() to a text field and it would be stored in the database. Then when the data is displayed on the form again, your script (now saved in the database, will run on the web page!).

AntiXSS is a great library that possesses more capabilities than the built-in Html.Encode. You can find it via Nuget Package Manager.

https://www.nuget.org/packages/AntiXSS/

Upvotes: 0

Rakesh Sojitra
Rakesh Sojitra

Reputation: 3658

You can also use. There is typo at var myForm = $("#myForm");

string decodeString = Server.UrlDecode("Key%20Date%20%26%20Times");

OR

string decodeString = Uri.UnescapeDataString("Key%20Date%20%26%20Times");

Upvotes: 0

mybirthname
mybirthname

Reputation: 18127

string decodeString = HttpUtility.UrlDecode(@"Key%20Date%20%26%20Times");

Use UrlDecode method of HttpUtility class.

Upvotes: 11

Related Questions