As a total newbie to web-based programming, I'm having trouble understanding why the pattern attribute field below fails to check the validity of the text field due to my javascript.
<form id="aForm">
<input type="text" pattern="^[ a-zA-Z0-9,#.-]+$" id="address" title="Standard address"/>
<input type="submit" id="open" value="Start"/>
</form>
The form contents are then sent to a javascript file which then sends it to the server via a websocket as in the code fragment below. However it ignores validating the form through the pattern attribute.
$(document).ready(function() {
$("#open").click(function(evt) {
evt.preventDefault();
var form = $('#aForm').serialize();
webSocket = new WebSocket("ws://localhost:9999/mh");
webSocket.onopen = function()
{
webSocket.send(form);
};
REST OF CODE....
It seems that for some reason this prevents the text from being checked before it's sent. I would like to know why and how to ensure that the form is validated by the pattern attribute.
Thanks
The HTML5 form validation is only performed when you're trying to actually submit the form, or when you explicitly use JavaScript to validate it1.
Since your JavaScript is bound to a different event (button click), form validation is not performed at that point. You can solve this by:
binding your submission to the form's submit event instead of button click, or
using the form validation API at the very beginning of your script.
I strongly recommend the first option. It makes more semantic sense and works right when the form is submitted though other methods (I don't remember if the button click will be simulated when someone presses Enter in the text field, and it definitely won't be triggered if JavaScript calls $('#aForm').submit() programmatically...).
1 At least, those are the only places I noticed - it's possible there are other events/circumstances when validation is done as well.
Related
I'm trying out a simple CSRF attack and ran into an issue.
If I have a dummy site containing this form:
<form action="somewebsitetoexploit.com/someformpage" method="GET" hidden>
<input type="password" autocomplete="off" name="password_new" value="hacked"><br>
<input type="password" autocomplete="off" name="password_conf" value="hacked">
<input type="submit" value="Change" name="Change">
</form>
My original idea was to have this form "self submitting" by having a script tag call submit on the form on page load to automatically change the user's password when they visit the page:
<script>
window.onload = (_) => {
const form = document.getElementsByTagName("form")[0];
form.submit();
};
</script>
This looked like it worked, but the password failed to change. When looking at the GET parameters, I realized that it was because it didn't include the Change parameter (the submit button itself). It produced:
?password_new=hacked&password_conf=hacked
Instead of:
?password_new=hacked&password_conf=hacked&Change=Change
And I'm guessing this is causing it to fail a validation check on the backend.
It seemed hacky, but I was able to fix it by having it click the submit button instead of submiting the form directly:
<script>
window.onload = (_) => {
const submit = document.getElementsByName("Change")[0];
submit.click();
};
</script>
I looked over the relevant MDN page, and it notes that calling submit has two differences from clicking the submit button:
No submit event is raised. In particular, the form's onsubmit event handler is not run.
Constraint validation is not triggered.
It isn't immediately clear though why the onsubmit not firing would affect what GET parameters are sent, so I'm not sure if that's relevant.
Obviously for forms that use GET as the method, I could just construct the URL with query parameters manually and not worry about having a form. For the sake of learning though (and in case I want to manipulate a form that uses POST in the future), I'd like to understand what's happening here.
The page I'm trying to "attack" is the password change CSRF page of DVWA.
A form can have multiple submit buttons, with different names and/or values.
When you click a submit button and the default submit action takes place, the name and value of the button you clicked are included in the form parameters when the form is submitted.
When you call the submit() method there's no associated button click, so no button name and value will be included in the parameters. If the form has multiple submit buttons, which button would you expect it to send?
This behavior is specified in the HTML standard:
The submit() method, when invoked, must submit the form element from the form element itself, with the submitted from submit() method flag set.
Where submission carries out the many steps described here:
When a form element form is submitted from an element submitter (typically a button), optionally with a submitted from submit() method flag set, the user agent must run the following steps:
...
Let submitterButton be null if submitter is form. Otherwise, let submitterButton be submitter.
...
Let entry list be the result of constructing the entry list with form, submitter, and encoding.
Where the entry list eventually results in a string like ?password_new=hacked&password_conf=hacked.
If you submit the form by pressing the button (either manually or programatically), submitter is set to the button, so the entry list includes the button.
If you submit the form by using .submit(), submitter is set to the form, so submitterButton is set to null, so the entry list does not include it.
The construction of the entry list skips buttons which are not submitter:
For each element field in controls, in tree order:
If any of the following is true:
The field element is a button but it is not submitter.
Then continue.
I'm trying to use the below search form and js to search my site. However, whenever you type a word in the form and click submit the form them takes the users browser to http://example.com/?s=searchterm , but I want it to take them instead to http://example.com/searchterm and totally leave out the characters ?s=
<script type="text/javascript">
function submitform()
{
document.forms["searchsite"].submit();
}
</script>
<form id="searchsite" action="/">
<input type='text' name='s' placeholder='search'>
Submit
</form>
Any positive advice? Btw, no, I don't believe I can use htaccess and mod_rewrite since I already have rules set.
You could set an onsubmit handler to intercept the form’s submission and replace the default action with setting the location href. This relies on JavaScript being enabled in the client side:
<form id="searchsite" action="/" onsubmit="javascript:location.href=this.action + encodeURIComponent(this.elements.namedItem('s').value); return false;">
This escapes the search term so that if the user enters something with ? or / in it, the server will interpret that as part of the path instead of thinking that the client is trying to send a querystring or access some subdirectory. The return false; states that the browser should stop its normal form submission procedure since the onsubmit handler has already updated location.href, which will cause the browser to start navigating as soon as the onsubmit handler returns.
However, you really should supplement this with server-side code. For something this simple, the JavaScript can be there to make your URIs pretty while skipping an HTTP redirect (so that the browser goes directly to the requested page slightly faster than otherwise). But you should really have a server-side redirect that gets triggered whenever the GET s parameter is sent.
Extra note: you should really replace your submission script with a <button/>, like:
<button type="submit">Submit</button>
and just drop your <a/> and <script/> tags completely. You get all of the functionality you need by overriding the form submission handler itself, no need to try to intercept button clicks, etc. With this change, your form should now work when the user presses ENTER instead of requiring the user to TAB to the <a/>. Use the intended HTML elements for their intended purposes and hook into the right events ;-).
I assume that your question is only about the client-side of the code and that you already have figured how to get your server-side code to read the value from the URI path. Figuring out how to read the value, if it is submitted this way, would take me some time to research and would require more information about your server-side setup.
Instead of submitting the form, build the URL and then set the location. You can add an ID to the search term (s in this case) and then simply build the URL:
var searchTerm = document.getElementById("s").value;
document.location = "http://example.com/" + searchTerm;
I'm relatively new to programming, but understand the basics of HTML, CSS, and Javascript (including jQuery). Due to my greenness, I'd appreciate it if answers contained both a simple solution and a reason as to why the solution works. Thanks!
So I've got a form, with a text input and a submit button:
<form>
<input type="text">
<button type="submit">Submit</button>
</form>
When the user types data into the text field and clicks submit, how do I gain access to this data? If a user inputs their name, how do I grab that information? I don't intend to store it or write it anywhere, just to hold onto it as a variable in javascript, which I'll assign to a jQuery cookie.
So how do I access the data that the user has submitted, preferably using only Javascript (with jQuery)? Thanks for the help!
You access the data on the server side (in PHP via $_POST['username'] for example). The form sends data to your sever for any named input, so you would probably have to change the input to:
<input type=text name=username>
If you want to access it on the client side (with JavaScript), you can do that too, but you have to prevent the form from submitting:
$("form").on('submit', function (e) {
$.cookie('username', $(this).find('[name=username]').val());
//stop form from submitting
e.preventDefault();
});
say you had an html input tag such as:
<input id="textfield" type="text">
using javascript, you can store the value of that field in a variable like this:
var inputvalue = $('#textfield').val();
of course, you'll need something to run the script.
the reason this works is that the the textfield is an object. you might think of it as a tree trunk with different branches coming out. one of these "branches" is the value contained inside of it. since you know jquery, you know that $('#textfield') gets the element by a selector. the period says we're getting one of the branches, and "value" says we want the branch that tells what's in the textfield.
hope this helps.
I'm using MVC 3 with Razor and using unobtrusive client validation. Things are working great, but I want to be able to reset the form if a user decides he wants to start over or cancel his action. It seems that there is a lot of meta data attached to each form element when using the validation.
<input type="text" value="" name="User.FirstName" id="User_FirstName" data-val-required="The First Name field is required." data-val-length-max="50" data-val-length="The field FirstName must be a string with a maximum length of 50." data-val="true" class="text-box single-line">
The jQuery snippet here shows my problem. When you try to manually reset the value of the text field, some other javascript is intercepting execution after I clear the value and it sets it back to what it was:
$("#btnReset").click(function () {
alert($("#User_FirstName").val());
$("#User_FirstName").val("");
alert($("#User_FirstName").val());
});
I'm looking for pointers here on how to clear form values when a user clicks a button. It seems like such a simple task, but I can find no documentation how to accomplish this and I haven't found anything here or elsewhere to help.
I was using an html input of type reset rather than the button type. The reset should not have been used in this case.
If an HTML form field has focus and you hit enter, the form will be submitted (unless you've done fancy things to bypass that). Weirdly though, if JavaScript adds a field into the form, that enter-to-submit behavior appears to break. For example:
http://jsfiddle.net/SChas/1/
function goose() {
document.getElementById("addhere").innerHTML="<input name=goose value=honk>";
}
function checkForm() {
alert("ok");
}
--
<form onsubmit="checkForm();">
<input name="duck" value="quack">
<div id="addhere"></div>
</form>
<button onclick="goose();">add a goose</button>
(This is a contrived example attempting to be as concise as possible. The original code involved is more modern code with events attached in JavaScript, etc. But this is the simplest code that replicates the issue. Also, it is necessary in the real use case to dynamically modify the form by adding/removing fields.)
Anyway, you'll get a form that has a single field with a value "duck". Click into it and hit enter, and the form will submit (you'll see an "ok" alert and then JSFiddle will tell you not to post!).
However, if you click "add a goose", you get a new field. And now, you cannot hit enter to submit the form.
Why is this happening? I can't find anything about this behavior via google, perhaps I'm using the wrong search terms. But it happens in IE on Windows and Chrome and FF on OSX at least. So it seems like an intentional, perhaps to-specification, behavior. Is it some kind of security protection?
And, is there any way to restore the enter-to-submit behavior on the form once a field is inserted? A way other than to add onkey* events to the input fields?
FWIW, it doesn't seem to matter if the inputs are added via DOM methods (appendChild), or setting the innerHTML, using jQuery or old fashioned JavaScript.
This is because the enter-to-submit behaviour only happens when it's the only input on the form.
You can restore it by putting a input with type=submit on the form, it doesn't even have to be visible.
Check it out: http://jsfiddle.net/SChas/10/