method=post enctype=text/plain are not compatible?
[Revised]
The answer is, because PHP doesn't handle it (and it is not a bug):
https://bugs.php.net/bug.php?id=33741
Valid values for enctype in <form> tag are:
application/x-www-form-urlencoded
multipart/form-data
The first is the default, the second one you need only when you upload files.
@Alohci provided explanation why PHP doesn't populate $_POST
array, but store the value inside a variable $HTTP_RAW_POST_DATA
.
Example of what can go wrong with text/plain
enctype:
file1.php:
<form method="post" enctype="text/plain" action="file2.php">
<textarea name="input1">abc
input2=def</textarea>
<input name="input2" value="ghi" />
<input type="submit">
</form>
file2.php:
<?php
print($HTTP_RAW_POST_DATA);
?>
Result:
input1=abc
input2=def
input2=ghi
No way to distinguish what is the value of input1
and input2
variables. It can be
- input1=
abc\r\ninput2=def
, input2=ghi
, as well as - input1=
abc
, input2=def\r\ninput2=ghi
No such problem when using the other two encodings mentioned before.
The difference between GET and POST:
- in GET, the variables are part of URL and are present in URL as query string, therefore they must be URL-encoded (and they are, even if you write
enctype="text/plain"
- it just gets ignored by the browser; you can test it using Wireshark to sniff the request packets), - when sending POST, the variables are not part of URL, but are sent as the last header in HTTP request (POSTDATA), and you can choose whether you want to send them as
text/plain
orapplication/x-www-form-urlencoded
, but the second one is the only non-ambiguous solution.
What does enctype='multipart/form-data' mean?
When you make a POST request, you have to encode the data that forms the body of the request in some way.
HTML forms provide three methods of encoding.
application/x-www-form-urlencoded
(the default)multipart/form-data
text/plain
Work was being done on adding application/json
, but that has been abandoned.
(Other encodings are possible with HTTP requests generated using other means than an HTML form submission. JSON is a common format for use with web services and some still use SOAP.)
The specifics of the formats don't matter to most developers. The important points are:
- Never use
text/plain
.
When you are writing client-side code:
- use
multipart/form-data
when your form includes any<input type="file">
elements - otherwise you can use
multipart/form-data
orapplication/x-www-form-urlencoded
butapplication/x-www-form-urlencoded
will be more efficient
When you are writing server-side code:
- Use a prewritten form handling library
Most (such as Perl's CGI->param
or the one exposed by PHP's $_POST
superglobal) will take care of the differences for you. Don't bother trying to parse the raw input received by the server.
Sometimes you will find a library that can't handle both formats. Node.js's most popular library for handling form data is body-parser which cannot handle multipart requests (but has documentation that recommends some alternatives which can).
If you are writing (or debugging) a library for parsing or generating the raw data, then you need to start worrying about the format. You might also want to know about it for interest's sake.
application/x-www-form-urlencoded
is more or less the same as a query string on the end of the URL.
multipart/form-data
is significantly more complicated but it allows entire files to be included in the data. An example of the result can be found in the HTML 4 specification.
text/plain
is introduced by HTML 5 and is useful only for debugging — from the spec: They are not reliably interpretable by computer — and I'd argue that the others combined with tools (like the Network Panel in the developer tools of most browsers) are better for that).
Form not working with Mailto correctly
You forgot to set the name
attribute! The subject you can set as a parameter (subject
) on the email address. Try the following code:
<form action="mailto:example@example.com?subject=Test" method="post" enctype="text/plain" class="form-horizontal"> <div class="form-group"> <label for="name" class="col-sm-2 control-label">Name</label> <div class="col-sm-10"> <input type="text" class="form-control" name="name" id="name" placeholder="Name"> </div> </div> <div class="form-group"> <label for="company" class="col-sm-2 control-label">Company</label> <div class="col-sm-10"> <input type="text" class="form-control" name="company" id="company" placeholder="Company"> </div> </div> <div class="form-group"> <label for="email" class="col-sm-2 control-label">Email</label> <div class="col-sm-10"> <input type="email" class="form-control" name="email" id="email" placeholder="Email"> </div> </div> <div class="form-group"> <label for="message" class="col-sm-2 control-label">Message</label> <div class="col-sm-10"> <textarea class="form-control" rows="3" name="message" placeholder="Your Message"></textarea> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">Submit</button> </div> </div></form>
Post request to include 'Content-Type' and JSON
Browsers do not support JSON as a media type for form submissions (the supported types are listed in the spec).
The only way to make such a request from a web page is to use the XMLHttpRequest object.
Google provide a JavaScript library (which wraps XMLHttpRequest) that can interact with their URL Shortener API.
Javascript Submit is not Sending POST to php file
Remove enctype="text/plain"
from the form tag, PHP doesn't support it.
See: method="post" enctype="text/plain" are not compatible?
How do I POST with multipart form data using fetch?
You're setting the Content-Type
to be multipart/form-data
, but then using JSON.stringify
on the body data, which returns application/json
. You have a content type mismatch.
You will need to encode your data as multipart/form-data
instead of json
. Usually multipart/form-data
is used when uploading files, and is a bit more complicated than application/x-www-form-urlencoded
(which is the default for HTML forms).
The specification for multipart/form-data
can be found in RFC 1867.
For a guide on how to submit that kind of data via javascript, see here.
The basic idea is to use the FormData object (not supported in IE < 10):
async function sendData(url, data) {
const formData = new FormData();
for(const name in data) {
formData.append(name, data[name]);
}
const response = await fetch(url, {
method: 'POST',
body: formData
});
// ...
}
Per this article make sure not to set the Content-Type
header. The browser will set it for you, including the boundary
parameter.
after enctype=multipart/form-data request not working
Why do you need to add it then? Just keep it out.
If you need it in order to upload a file by <input type="file">
which you intend to add later on, then you should put @MultipartConfig
annotation on your servlet, so that request.getParameter()
will work and that all uploaded files can be retrieved by request.getPart()
.
@WebServlet("/Relay")
@MultipartConfig
public class Relay extends HttpServlet {
// ...
}
See also:
- How to upload files to server using JSP/Servlet?
Related Topics
Are PHP Variables Passed by Value or by Reference
PHP Code to Convert a MySQL Query to Csv
What's the Difference Between Echo, Print, and Print_R in PHP
Simple PHP Post-redirect-get Code Example
Change Cart Item Prices in Woocommerce 3
PHP Preg_Match to Find Multiple Occurrences
Cannot Use Object of Type Stdclass as Array
Build Select Query With Dynamic Number of Like Conditions as a MySQLi Prepared Statement
How to Get Input Field Value Using PHP
PHP/MySQL Insert Row Then Get 'Id'
PHP: Convert Any String to Utf-8 Without Knowing the Original Character Set, or At Least Try
PHP Datetime::Modify Adding and Subtracting Months
MySQLi Bind_Param() Expected to Be a Reference, Value Given
MySQLi Equivalent of MySQL_Result()