HTML Form works with GET but not with POST - html

I'm running Firefox 2.0.0.14.
I have a form on a webpage which is working fine with the GET method.
I'm using a plugin to view my browser's HTTP request when submitting the form, and here it is :
GET /postComment.php?review=2&comment=Testing HTTP/1.1
...
However, if I make the simple change from method=GET to method=POST on the form:
GET /postComment.php HTTP/1.1
...
It isn't even attempting to POST.
Any possible reasons for this, under any circumstances?
EDIT: Here is the form:
<form method=POST action="postComment.php"><input type=hidden name=review value="2"><input type=submit value="Postit">
</form>

Is the action parameter of the form tag set? Could Javascript be intercepting the post? Some HTML from your form would be helpful, or an example link :)

I'm guessing your plugin is not capturing the POST variables. Since the output of your plugin is:
GET /postComment.php HTTP/1.1
How are you catpuring your POST varables? $_POST['key'] or $_REQUEST['key'] should contain your value if the form action and method are set properly.
POST will not be found in the query string.
EDIT:
if you are trying to capture the post value, you can check it with something like this:
if (isset($_REQUEST['submit'])) {
echo $_REQUEST['review'];
}
or
if (isset($_POST['submit'])) {
echo $_POST['review'];
}
Acorn

I would start by making sure your HTML is valid XHTML. Wrap attribute values in quotations and end the input elements with />. Use a valid DOCTYPE.
Also, try changing the value of the submit button to "submit" (as that is the default).
Try it out in different browsers, including the latest version of Firefox.

Firstly, your <form> tag needs to be adjusted:
<form method="post" ... >
Secondly, I have a function called debugArray that I use to spit out misbehaving arrays. It's very handy:
function debugArray($array){
echo("<pre>");
print_r($array);
echo("</pre>");
}
Then, call it in your code like this:
debugArray($_POST);
By looking at the entire contents of the $_POST array, you can see exactly what is being sent, what is not, and how it is being sent.
I'm willing to wager that one of the following is true:
You have a spelling mistake in a field name, remembering that names are case sensetive.
Your form field is outside your <form> tags.
You have a value that is not being escaped correctly, or otherwise being dropped from the $_POST for whatever reason.
Edit: And I would also be inclined to update your copy of Firefox.

I was having the same problem, till I remembered that my .htaccess file hides my PHP extension, and for reasons that someone else can explain (tech stuff) All I did was remove the .php extensión in the action property and it worked.
So, I went from:
action="folder/folder/file.php"
To:
action="folder/folder/file"
And the print_r($_POST) displayed the full array
I really Hope this helps someone else with the same problem.
And if anyone can technically explain why this is happening, it would be very educational 🙃

Related

How to post metrics to InfluxDB with a simple HTML form?

I'm trying to send a 0 or a 1 to a database within my InfluxDB instance via a POST request from an HTML form. I've done this successfully lots of times through curl, but I can't make it work with a simple HTML form. Consider this HTML code:
<!doctype html>
<!-- this file is called like http://my.influx.server/my_page_name.html -->
<html>
<head>
<title>my simple html/influx sender</title>
<meta charset="UTF-8"/>
</head>
<body>
<form action="http://my.influx.server:8086/write?db=db_name" method="post" enctype="text/plain">
<input name="data" type="hidden" value="my_measurement,tag_name=stuff value=1"/>
<input type="submit" value="insert 1"/>
</form>
<form action="http://my.influx.server:8086/write?db=db_name" method="post" enctype="text/plain">
<input name="data" type="hidden" value="my_measurement,tag_name=stuff value=0"/>
<input type="submit" value="insert 0"/>
</form>
</body>
</html>
The curl command for sending a 1 would be like:
curl -i -XPOST 'http://my.influx.server:8086/write?db=mydb' --data-binary 'my_measurement,tag_name=stuff value=1'
So I tried to make a simple HTML form with just 2 buttons. The code above is the closest I could get to at least try to process the "line interface" syntax, however I'm getting either an error message or just no response and I don't get anything in my InfluxDB. The error message from the code above is:
unable to parse 'data=my_measurement,tag_name=stuff value=1\r': invalid number
If you have a close look at the end of the string, you see a \r that obviously gets added and I suspect that this breaks number parsing (I had something similar some time ago), but at least this seems to try to evaluate the line at all. However, I haven't found a way to remove or avoid the \r. Has someone an idea how to achieve this?
Also, please consider the following additional information:
I want it really simple, just a small HTML file with possibly a bit of JavaScript code, but I'd really like to avoid using PHP, jQuery and such. Also, I'm trying to get used to HTML5 as you might notice, but this shouldn't be the problem.
In this case, I don't need a timestamp for each key press, so instead of passing a timestamp I just use the current time. This is achieved by omitting the timestamp, so the string excluding the \r should be syntactically correct.
I also looked for alternatives, however there was only the idea to use JSON and this seems not to be supported any more due to performance reasons (which I wouldn't expect in my case).
The curl command uses the --data-binary parameter, but it seems I don't have anything like this in HTML. I'm aware of binary enctypes like application/x-binary, but they don't work, because they URL-encode the string and this won't pass the syntax check. The only enctype I found that worked at least close enough is text/plain.
I'm also aware of form data not being sent, if the corresponding <input> element has no name attribute. Then I noticed that the curl string was built like my_measurement,tag_name=stuff value=1, possibly multiple such lines separated by \n, which is not like POST key-value-pairs as in a=1&b=2 (i. e. there is no key, that would be the name attribute). Trying to trick it with name="my_measurement,tag_name" and value="stuff value=1" (which would resemble the original string) was not successful and I still couldn't figure out, which key is expected. I tried with content, query etc. and ended up using data. I kept this then because in the docs they talk about "data" and none of the keys made any difference, as long as one is provided. I suspect InfluxDB to just use the first POST variable ignoring the name, but I can't find any clear statement on this.
I also tried several invisible <input> types like just hidden or a regular textbox hidden by style. This made no difference. Neither did visible elements.
I also considered using AJAX, but I couldn't find anything useful about binary POSTs without key-value content. I even would cope with a page that only works e. g. for Firefox for now, so I don't need to switch between different AJAX object creation algorithms and such (yes, I know, jQuery helps, but see first point above).
EDIT 1: I tried to reproduce the error with curl:
curl -i -XPOST 'http://my.influx.server:8086/write?db=home' --data-binary 'my_measurement,tag_name=stuff value=1\r'
This led to the error message:
unable to parse 'my_measurement,tag_name=stuff value=1\\r': invalid number
with headers:
HTTP/1.1 400 Bad Request
Content-Type: application/json
Request-Id: ...
X-Influxdb-Build: OSS
X-Influxdb-Error: unable to parse 'my_measurement,tag_name=stuff value=1\r': invalid number
X-Influxdb-Version: 1.7.9
X-Request-Id: ...
Date: ...
Content-Length: 78
I conclude:
\r seems to be differently encoded in the error message (characters \ and r instead of an actual carriage return), but in the header it's only \r, however it doesn't make a difference regarding the parsing error, so this is comparable.
There is obviously no key name involved, so this is still different from my attempt above.
EDIT 2: I found out how to show the request headers from a call to curl. The command is:
curl -v -XPOST 'http://my.influx.server:8086/write?db=db_name' --data-binary 'my_measurement,tag_name=stuff value=1'
The relevant portion of the output of the command is:
> POST /write?db=db_name HTTP/1.1
> Host: my.influx.server:8086
> User-Agent: curl/7.58.0
> Accept: */*
> Content-Length: 37
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 37 out of 37 bytes
< HTTP/1.1 204 No Content
< Content-Type: application/json
< Request-Id: ...
< X-Influxdb-Build: OSS
< X-Influxdb-Version: 1.7.9
< X-Request-Id: ...
< Date: Sat, 25 Jan 2020 10:54:11 GMT
I conclude:
Content type of the request invoked by curl with --binary-data is application/x-www-form-urlencoded.
Unfortunately I couldn't achieve to see the actual request body, so I'll try again with some URL-encoded variants. However, my_measurement,tag_name=stuff value=1 is 37 characters as in the request header, so I assume there is no key name like data involved. Currently, I get the same error message I had before I posted this question: unable to parse 'data=my_measurement%2Ctag_name%3Dstuff+value%3D1': missing fields
The \r is gone, but I still can't send data without a key name and the whole string is invalid due to URL-encoding. How to get rid of the URL-encoding?
Finally, I found a solution with JavaScript that worked. This Mozilla doc page was the key to a POST form without keys. My HTML page now looks like this:
<!doctype html>
<!-- this file is called like http://my.influx.server/my_page_name.html -->
<html>
<head>
<title>my simple html/influx sender</title>
<meta charset="UTF-8"/>
</head>
<body>
<form id="form1">
<button>insert 1</button>
</form>
<form id="form0">
<button>insert 0</button>
</form>
<script>
function sendData(value)
{
const str = "my_measurement,tag_name=stuff value=" + value;
const xhr = new XMLHttpRequest();
xhr.addEventListener("load", function(event) {
alert("Success");
});
xhr.addEventListener("error", function(event) {
alert("Error");
});
xhr.open("POST", "http://my.influx.server:8086/write?db=db_name");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(str);
}
const form0 = document.getElementById("form0");
const form1 = document.getElementById("form1");
form0.addEventListener("submit", function(event) {
event.preventDefault();
sendData(0);
});
form1.addEventListener("submit", function(event) {
event.preventDefault();
sendData(1);
});
</script>
</body>
</html>
Note the stripped-down form definitions: There are no actions, methods or enctypes any more, as they are set via JavaScript. Also, there is no regular submit element, instead it is a regular button, however I don't know if this is needed. I'll investigate that later.
The main part is in the script tag underneath the forms. A function sendData prepares an XMLHttpRequest object for POSTing a prepared string and invokes its send method. This function is used in the submit events of each form. Also, this function registers event handlers for successful and failed requests.
The lines below the sendData function identify the forms and register event listeners on their submit event. Each listener prevents its form from submitting in a regular fashion and invokes the appropriate sendData call instead, which will successfully insert values into InfluxDB.
Be aware, though, there is still no guarantee to detect every error. I tried to insert a string into an integer field, which failed, but I still got the "Success"-alert. I'm going to investigate that later.
So in total, I see this problem as sufficiently resolved for my purposes and I hope this helps anyone stumbling across it.
This was a pretty useful post, I ran into this issue with the Sigfox backend and callbacks.
If you put an & at the end of the URL and use content type text/plain the \r\n issue is solved.

Promo Code Validation

I need to validate a Promo Code for one of my html Booking form field. If the entered promo code is correct, users can submit the Booking details. Only one unique promo code. Something like "15OFFNOW" How should I do it? Please help.
Thanks.
First, don't put the promo code in your page. Anyone can see it.
I would do this, but it depends on actually functionality.
Do client side check (this can be bypassed by a malicious user)
Do server side check
Do client side check
Use a good non-reversible hashing algorithm and verify what you have in the prom text box to the hash you have stored in a JavaScript variable or in a data-hash attribute.
So if hash(text box value) == valueOf(data-hash), then proceed to sever validation.
Do server side check
In server no need of hash. Just check the post string with the promo code you have.
i try your code
<form method="post">
<input class="form-control form-control-light bdr-2 rd-0" required
data-label="Promo Code"
data-msg="Please enter a valid promo code."
type="text" name="promo-code"
placeholder="Promo Code"
pattern="15OFFNOW" required>
<input type="submit" value="submit"/>
</form>
validation is work . show this message .
You can use Javascript for that , I fyou want to match promocode or you can validate it at backend using any backend language like PHP or java
for JQuery
//previous Ajax code here
if($("#input_id").val() !== "15OFFNOW"){
return false ;
}
// here you can proceed for Ajax request
You are looking for an input pattern, also called regexp (though I would instead suggest doing it js way (but not global) or on server side as advanced users can simply inspect html code). Most probably something like this
<input type="text" name="promo" pattern="15OFFNOW" required >
Also, please try googling it, there're similar questions like this answered also on StackOwerflow, e.g.
html: Can we match an exact string using html pattern attribute only?
js & php: check if input value not equal to integer then don't submit form

Why do we put "?" in action = "?"

When I was learning Php with Mysql, I got a problem :
<form action="?" method="POST">
.
.
.
</form>
Why do we put "?" in the action attribute?
PS: this form was for inserting text into a database.
Actually, I have an Index.php file which is the controller, and 2 files (form.html.php and joke.html.php as templates). In the tutorial, I first clicked on a link "add joke" to include the form.html.php file and in this form there is <form action="?"> </form> and a submit <input>. When I click on submit, the controller index tests and executes the inserted SQL query.
Thanks.
Personally don't ever do that.... Use action="action.php" or use action="" post to the current URL.
Not sure what you are trying to accomplish with ? in the action attribute.
"We" don't and "You" shouldn't do so either.
If you want to POST the data to the current URL, leave it empty, i.e. action="".
If you want to POST to another URL, put that URL in there, e.g. action="save.php".

Is there a way for HTML form to submit default value?

Is there a way (without JS) to make input fields POST a default value in case some input fields were blank when the submit was executed?
In other words: I want to avoid on server side reciving stuff like
"ID=&PW="
<form>
<input name="ID" value="stuff"/>
<input name="PW" value="stuff"/>
</form>
setting the value doesn't really help as the user still can clean the input field by him self.
There is no way to do so in pure HTML. Even if you use JS to setup defaults, someone can intercept and modify HTTP Request.
Never trust input values. You can't assume their values.
No. Not without JavaScript.
...but it would be so easy with JavaScript. Not that I advocate inline scripts, but how about:
<input name="ID" value="stuff" onBlur="this.value=this.value==''
? 'default'
: this.value;" />
The Javascript you see is a simple ternary operator, following the pattern:
myVar = condition ? valueIfTrue : valueIfFalse;
So it's checking if the input is blank. If so, set it to a default; if not, let it be.
You should simply enforce the default value server-side. Otherwise the user will always have the ability to trip you up. You can use javascript to reduce the chance of this happening but javascript will always be exposed to the user. Html doesn't have a method for this and even if I'm wrong and it does, or does in the future - such a thing is ALSO exposed to the user.
You're talking about using strtok. I'd recommend simply breaking the tokenizing out twice. Once for the &, and then within each of those results again for the = (obviously if the second result of each pair is blank or null, substituting the default). Otherwise, tokenize it yourself, still on the server.

Input value doesn't display. How is that possible?

This must be something utterly stupid that I've done or am doing, but I have an input with a value attribute that simply isn't being displayed:
<div class="input text required">
<label for="Product0Make">Make</label>
<input name="data[Product][0][make]"
type="text"
maxlength="255"
value="AC Make"
id="Product0Make">
</div>
Has anyone ever seen this before? Do I have some kind of typo that I'm just blind to? For whatever it may be worth, here's the CakePHP code that's generating this line:
<?php echo $this->Form->input( 'Product.' . $index . '.make', array( 'default' => $product['Product']['make'] ) ) ?>
I have a small form with a handful of text inputs, 1 textarea and 2 selects. None of the text input values display, but everything else is fine.
Any thoughts would be appreciated. I can't even believe I'm having to ask this question, but that's how crazy it's making me.
Argh. I knew this was going to be something beyond stupid. There was a bit of Javascript that was clearing data. The clearing was useful in other places, but I didn't know it was executing so it was a serious pain to track down. Once I prevented the clearing in this scenario, my values actually appeared. Because I was looking at the code in web inspector, I assumed that it would be a "live" view, but I guess that's not entirely true.
Thanks for your help, everyone.
For my side, it was a problem only for Firefox.
I resolved by adding the attribute autocomplete="off" in the input field.
<input type="text" value="value must appear" autocomplete="off"/>
Mine was related to AngularJS
I was trying to put both an HTML Value and an ng-Model, thinking that the ng-Model would default to the Value, because I was too lazy to add the Model to the $scope in the Controller...
So the answer was to assign that default value to the $scope.variable in the controller.
For me it was browser caching. Changing the URL string or clearing history can help.
For Googler's who may have the same issue: This can happen if you have a non-numeric value in a number type input field.
For example:
<input type="number" value="<? echo $myNumberValue; ?> "/>
This will show nothing even though Dev tools says the value is there, since the extra space after ?> makes it non-numeric. Simply remove the extra space.
Are you confusing the uses of the 'default' and the 'value' parameters for $html->input()?
If you're are using 'default' => $product['Product']['make'] and $this->data is present, the field will not be populated. The purpose of the 'default' parameter is to display a default value when no form data ($this->data) is present.
If you want to force display of a value, you should use the 'value' parameter instead. 'value' => $product['Product']['make']
For me it was because I was using the <input> tag without enclosing it inside a <form> tag
Had a similar problem with input value retrieved via ajax, correctly set and verifiable via browser console, but not visible. The issue was another input field having the same id, and it was not evident because of several JSP files included, many of them having forms.
I even set autocomplete to "off" with no result. I ended up putting the next jquery snippet at the document.ready event.
myForm.find("input").each((i, el) => {
$(el).val($(el).attr("value"));
});
Adittionally, this would be the equivalent in pure es2015:
document.querySelectorAll("myForm input").forEach(el => {
el.value = el.getAttribute("value");
});
If your not using a precompilor like Babel and you need compatibility for old browser's versions, change the "(el) =>" for "function(el)". I tried both codes in my scenario and worked fine.
For me the problem was that I had multiple inputs with the same id. I could see the value in the field, but reading it via javascript gave an empty value because it was reading a different input with the same id - I was surprised that there was no javascript error, just could not read the values I could see in the form.
For me it was wrong number format: Chrome expected "49.1", but ASP.NET passed "49,1", and it just didn't display!
<input type="number" value="49,1"/> // Should have been 49.1 !!!
Same problem occured on electron:
I was clearing the field with document.getElementById('_name').value = '' instead of document.getElementById('_name').setAttribute('value', "").
So I guess simple quote broke the field or input has a second value hidden attribute because I could rewrite on the fields and it won't change the value on the inspector
I had the same problem of #Rob Wilkerson, a onchange() was cleaning the value of the input with "", so i changed to 1. Such a dumb problem!
HTML
<input class="form-control inputCustomDay" type="text" id="txtNumIntervalo" onkeyup="changeTipoOptions()" value="1" min="1" />
Jquery
$("#txtNumIntervalo").val(1);
Mine was related to Angular.
I just ran into the same issue recently and realized that when you use NgIf to display a template, the said template does not automatically use display the data from the variables in the component.
As a quick fix I used ngClass just to Hide it and display it.
If anybody happens to be here because their input with type="dateTime-local" is not displaying the value... the value must be in format YYYY-MM-DDThh:mm