A special case of using form data is handling file uploads.
There are two main form encoding types:
- application/x-www-form-urlencoded (the default)
- multipart/form-data
When you wish to include file upload elements, you must choose multipart/form-data as your form's enctype
(encoding) type.
All code used below can be seen in action as a complete example at https://github.com/iamjono/perfect-file-uploads.
An example HTML form containing the correct encoding and file input element might be represented like this:
<form
method="POST"
enctype="multipart/form-data"
action="/upload">
<input type="file" name="filetoupload">
<br>
<input type="submit">
</form>
Because the form is a POST method, we will handle the route with a method: .post
:
var routes = Routes()
routes.add(
method: .post,
uri: "/upload",
handler: handler)
server.addRoutes(routes)
Once the request has been offloaded to the handler
we can:
// Grab the fileUploads array and see what's there
// If this POST was not multi-part, then this array will be empty
if let uploads = request.postFileUploads, uploads.count > 0 {
// Create an array of dictionaries which will show what was uploaded
var ary = [[String:Any]]()
for upload in uploads {
ary.append([
"fieldName": upload.fieldName,
"contentType": upload.contentType,
"fileName": upload.fileName,
"fileSize": upload.fileSize,
"tmpFileName": upload.tmpFileName
])
}
values["files"] = ary
values["count"] = ary.count
}
As demonstrated above, the file(s) uploaded are represented by the request.postFileUploads
array, and the various properties such as fileName
, fileSize
and tmpFileName
can be accessed from each array component.
Note: The files uploaded are placed in a temporary directory. It is your responsibility to move them into the desired location.
So let's create a directory to hold the uploaded files. This directory is outside of the webroot directory for security reasons:
// create uploads dir to store files
let fileDir = Dir(Dir.workingDir.path + "files")
do {
try fileDir.create()
} catch {
print(error)
}
Next, inside the for upload in uploads
code block, we will create the action for the file to be moved:
// move file
let thisFile = File(upload.tmpFileName)
do {
let _ = try thisFile.moveTo(path: fileDir.path + upload.fileName, overWrite: true)
} catch {
print(error)
}
Now the uploaded files will move to the specified directory with the original filename restored.
For more information on file system manipulation, see the Directory Operations and File Operations chapters.