Vaadin Elements - Upload - Server-side

Server Communication

Background

The vaadin-upload element sends a FormData via an XMLHttpRequest. The encoding type used is multipart/form-data. It has been the standard way to upload files for ages, hence it is supported by almost all servers. Since this type can only be sent using the POST or PUT methods, we only support those.

In order to support simultaneous uploads, instead of reusing the same FormData and XMLHttpRequest, we create a new one for each file. It is therefore alright for the server to only consider receiving one file per request.

For the client-side, we use the ProgressEvent specification, available in all modern browsers.

Request Configuration.

Communication between the vaadin-upload element and the server-side can be completely configured using element properties or attributes, and events.

Configuration Properties

Property name Default value Description

target

''

 Server URL

method

POST

HTTP method used to send the files. Only POST and PUT are allowed.

headers

{}

A JSON map with key/values to send to the server in the Headers

timeout

0

Time limit in seconds to upload the file

formDataName

file

The name property used in the Content-Disposition header.

<vaadin-upload
  target="http://127.0.0.1:8080/upload/servlet.gupld"
  method="POST"
  accept="image/*,video/*"
  headers="{'Accept': 'application/json'}"
  timeout=15000
></vaadin-upload>

Configuring the Request with Events

There are certain events to modify the XHR before sending it, or the response when the request finishes.

upload-before

At this point, the XHR has not been opened yet, but you can set the server URL by setting the file.uploadTarget attribute. You can also reject the file at this point by preventing the default action.

uploader.addEventListener('upload-before', function(e) {
  e.detail.file.uploadTarget =
    'http://127.0.0.1:8080/upload/servlet.gupld?filename=' + e.detail.file.name;
});

uploader.addEventListener('upload-before', function(e) {
  if (e.detail.file.size > 10240) {
    e.detail.file.error = 'File is too large.'
  }
});

The upload-before event allows you to customize the name in the Content-Disposition upload request header for each uploaded file individually:

uploader.addEventListener('upload-before', function(e) {
  // Use the filename as a FormData name for the file
  e.detail.file.formDataName = e.detail.file.name;
});
upload-request

You can change the request headers before it is sent and append data keys to the request.

uploader.addEventListener('upload-request', function(e) {
  e.detail.xhr.setRequestHeader('Accept', 'application/json');
  e.detail.formData.append('documentId', 1234);
});

You can cancel sending the request to the server by calling event.preventDefault(). In this case, you can send the request manually. This allows you to upload the file directly in the request data instead of inside a FormData wrapper.

uploader.addEventListener('upload-request', function(e) {
  e.preventDefault();
  e.detail.xhr.send(e.detail.file);
});
upload-response

The event is dispatched when the server message was received, but before the component processes it. At this point, you can check the response and make the upload fail by setting the file.error property. If the event is default-prevented, the response is not checked for errors and the UI is not updated.

uploader.addEventListener('upload-response', function(e) {
  if (e.detail.xhr.status == 200) {
    e.detail.file.error = JSON.parse(xhr.responseText).error;
  }
});

Server Processing

How to write your server-side code to receive the file is out of the scope of this document. Nevertheless, we leave you with some links: