Why not use enctype=multipart/form-data always?
From the RFC that defines multipart/form-data
:
Many web applications use the "application/x-www-form-urlencoded"
method for returning data from forms. This format is quite compact,
for example:
name=Xavier+Xantico&verdict=Yes&colour=Blue&happy=sad&Utf%F6r=Send
However, there is no opportunity to label the enclosed data with a
content type, apply a charset, or use other encoding mechanisms.Many form-interpreting programs (primarily web browsers) now
implement and generate multipart/form-data, but a receiving
application might also need to support the
"application/x-www-form-urlencoded" format.
Aside from letting you upload files, multipart/form-data
also allows you to use other charsets and encoding mechanisms. So the only reasons not to use it are:
If you want to save a bit of bandwidth (bearing in mind that this becomes much less of an issue if the request body is compressed).
If you need to support really old clients that can't handle file uploads and only know
application/x-www-form-urlencoded
, or that have issues handling anything other than ASCII.
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).
Use `enctype=multipart/form-data` always or never?
When uploading a file in your form, you should specify the encoding as "multipart/form-data".
If you want to keep your form generic, omit this attribute in the form and directly override it using formenctype attribute of input or button elements (only possible in browsers with HTML5 support).
In your case, change:
<form action="upload.php" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Upload Image" name="submit">
</form>
to:
<form action="upload.php" method="post">
Select image to upload:
<input type="file" name="fileToUpload" id="fileToUpload" formenctype="multipart/form-data">
<input type="submit" value="Upload Image" name="submit">
</form>
Also, you can check this question where it was recommended to avoid always using enctype="multipart/form-data"
.
Every time I set my form to enctype=multipart/form-data the file upload data doesn't go into the database
Have you read PHP file upload docs?
http://php.net/manual/en/features.file-upload.php
$_FILES is an array, it contains uploaded files metadata and paths to uploded temporary files.
You have to handle all uploaded files and store them in your application.
You should include something like this in your PHP script:
<?php
// ...
if (!empty($_FILES['post_image'])) {
$filepath = '/path/to/uploads/directory/' . basename($_FILES['post_image']['name']);
if (move_uploaded_file(
$_FILES['post_image']['tmp_name'],
$filepath
)) {
echo 'File stored in ' . $filepath;
} else {
throw new Exception('File could not be stored');
}
// Here you can store $filepath in database
// ...
}
Please note that you should add some validation and protection agains common upload attacks.
Why does file upload not work without the enctype property?
The "multipart/form-data" enctype is specified by RFC 1867 which you can review here for more of a technical overview.
In HTML forms, data is represented as several fields. When using multipart/form-data as the enc type, the browser sends the form fields as a series of "parts" which each have a content-type header to describe the type of data stored in the part. This content-type is usually set to "text/plain" for normal form fields. This content-type is only sent by the browser when the multipart/form-data enctype is used.
For input elements of type "file", the content type is "application/octet-stream" or something similar which indicates to the server side software that the contents of the field are not typical plaintext but are instead the contents of a file and should be handled differently.
The reason input elements of type "file" do not work whenever "multipart/form-data" is not used is due to the fact that the server has no way of identifying that the contents of the field are any different from a normal text field (since the browser does not send the content-type unless multipart/form-data is used) so it handles the contents of the field as normal text. When the proper enctype is used and the server can properly identify what type of data the field contains, the server knows to handle the contents of the field as file data instead of text and can process it properly.
Why ajax upload file doesn't need enctype=multipart/form-data in the form tag?
You're posting the form content with ajax, so the attributes on the <form>
tag are irrelevant. Your own code is basically doing the work that the browser would do if the form were posted implicitly by the browser.
html form enctype=multipart/form-data
Change your method to POST:
<form name ="input" enctype="multipart/form-data" action = "addPhotograph.php" method = "post">
You cannot post your files via GET method.
Related Topics
With Ng-Bind-Html-Unsafe Removed, How to Inject Html
What Is Sr-Only in Bootstrap 3
What's the Difference Between Disabled="Disabled" and Readonly="Readonly" for HTML Form Input Fields
Is Either Get or Post More Secure Than the Other
How to Link to Part of a Page - Hash
How to Open Link in a New Tab in Html
Is It Valid to Have a HTML Form Inside Another HTML Form
I Need an Unordered List Without Any Bullets
Difference Between Id and Class in Css, and When Should I Use Them
Are Custom Elements Valid Html5
Font Awesome 5 on Pseudo Elements Shows Square Instead of Icon
Change Select Box Option Background Color
Difference Between HTML Div and Span Elements
Submit Form Using a Button Outside the ≪Form≫ Tag