Upload
Last updated
Last updated
Example of the upload control before selection:
Example of the upload control sending a file in the background, with progress bar and "Cancel" button:
XForms allows you to upload files with the XForms upload control:
The related section of the XForms model can look like this:
The file
element is the element storing the result of the file upload. The result can be stored in two ways:
As a URL: By specifying the type xs:anyURI
.
As Base64-encoded text: By specifying the type xs:base64Binary
. Base64 is a mechanism to encode any binary data using a 65-character subset of US-ASCII. Using this mechanism allows embedding binary data into XML documents, at the typical cost of taking 50% more space than the original binary data. For more information, please refer to the RFC.
The optional xf:filename
, xf:mediatype
, and xxf:size
(the latter is an Orbeon Forms extension) allow storing metadata about an uploaded file:
xf:filename
: stores the file name sent by the user agent
xf:mediatype
: store the media type sent by the user agent
xxf:size
: stores the actual size in bytes of the uploaded data
SECURITY NOTE: The file name and the media type are provided by the user agent (typically a web browser). Not only are they not guaranteed to be correct, but they must not be trusted.
The result of a file upload when using xs:anyURI
contains metadata parameters and typically looks like this:
NOTE: The metadata includes a signature placed by the <xf:upload>
control. This signature allows <xf:output>
to verify that signature and disallow display or download of file:
URLs not constructed by <xf:upload>
. This enhances the security of uploads.
The URL stored as the value of the upload is temporary and only valid until either:
the session expires,
the Java VM quits,
or a new file upload replaces the existing URI in the XForms instance.
The URL is only accessible from the server side, and will not be accessible from a client such as a web browser. It is not guaranteed to be a file:
URL, only that it can be read with Orbeon Forms's URL generator or <xf:output>
.
The contents of the file can be retrieved using the URL Generator. The result will be an XML document containing a single root element containing the uploaded file in Base64-encoded text.
NOTE: Using the xs:anyURI
type allows Orbeon Forms to make sure the uploaded file does not have to reside entirely in memory. This is the preferred method for uploading large files.
The result of a file upload looks as follows when using xs:base64Binary
:
In this case, the uploaded file is encoded an directly embedded into the XML instance. This is a good method to handle small files only, because the entire file is converted and stored in memory.
You can validate a file based on its name, mediatype, and size. Assume file metadata is stored into:
The following bind checks that if an uploaded file is present, the file size is no greater than 500,000 bytes and the mediatype is a JPEG image:
Note that Internet Explorer can send the image/pjpeg
mediatype.
SECURITY NOTE: The file name and the media type are provided by the user agent (typically a web browser). Not only are they not guaranteed to be correct, but they must not be trusted.
[SINCE Orbeon Forms 4.3]
The accept
attribute is simply passed to the web browser. As of 2013, most web browsers do support filtering files based on that attribute, as per the HTML specification. For example:
The accept
attribute is an XForms 2.0 feature. For backward compatibility, the mediatype
attribute is also supported.
SECURITY NOTE: This is not a guarantee that the file sent will have that mediatype, because some browsers do not support that feature, and even when it does, the browser must not be trusted.
With regular controls such as input, textarea, etc., upon a change of value by the user a small Ajax request is sent by the browser to the server to synchronize the data into the XForms data model.
With uploaded files, this is often not possible, because files can be very large and so take a significant amount of time to be sent to the server, up to minutes or even hours depending on file size and connection speed.
So there is a distinction to make between:
selection: the user selecting a file with the upload control's file selector
synchronization: the file data being fully sent to the server and available for processing by XForms
Orbeon Forms is able in most cases to synchronize files in the background: the user can keep working with the page while files are being uploaded.
Any files are selected but not synchronized upon a submission with replace="all"
, those files are synchronized then.
In other cases, the process works as follows:
as soon as the user selects a file with an upload control, the file is automatically scheduled for synchronization with the server
background synchronization starts as soon as possible:
immediately if no other upload is pending
when other pending uploads have completed
pending uploads can be canceled by the user with a Cancel button
while background synchronization is taking place, the user can keep interacting and updating the page
no boilerplate code or otherwise is needed to start synchronization!
By default, <xf:submission>
checks for uploads and interrupts the submission if:
the effective serialization is not none
there is a pending upload
for an upload control
which is relevant
and bound to the instance being submitted
If a submission detects that there is a pending upload, the submission terminates with:
dispatching the xforms-submit-error
event
with an event('error-type')
set to xxforms-pending-uploads
You can this way detect pending uploads on submission with code like:
This can be overridden with the xxf:uploads
AVT attribute:
In addition, the xxf:pending-uploads()
function returns the number of pending uploads. Example:
NOTE: xforms-select
is no longer dispatched when a file is selected.
By default, empty uploaded files are rejected. This behavior can be changed using the following property: