This post shows a WinJS/HTML solution to upload multiple images in Windows 8. The same method can apply to other binary files, not limited to images.
Requirement : use HTML POST to upload multiple images to a server at one shot with some form values
Solution : use FormData to build the raw data and use WinJS.xhr to post the data
Code :
/** * Select multiple images and upload to the server * @param string url: Server URL * @param array formFields: other form values to send * @return a Promise object */ function uploadMultipleImages(url, formFields) { return new WinJS.Promise(function (c, e, p) { var dataToSend = new FormData(); var filePicker = new Windows.Storage.Pickers.FileOpenPicker(); filePicker.fileTypeFilter.replaceAll([".jpg", ".jpeg"]); filePicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.picturesLibrary; filePicker.pickMultipleFilesAsync().then(function (files) { if (files.length === 0) { console.log("No file selected"); return; } if (formFields && formFields.length > 0) { formFields.forEach(function (formField) { for (var key in formField) { dataToSend.append(key, formField[key]); // Add field value } }); } var imgPromises = []; // Promises for all images access files.forEach(function (file, index) { imgPromises.push(file.openAsync(Windows.Storage.FileAccessMode.read)); }); WinJS.Promise.join(imgPromises).then(function (data) { // Wait for all promises for (var i = 0; i < data.length; i++) { // data[i] is the file stream var blob = MSApp.createBlobFromRandomAccessStream("image/jpg", data[i]); dataToSend.append(files[i].name, blob, files[i].name); } var options = { url: url, type: "POST", data: dataToSend }; WinJS.xhr(options).then(function (response) { c(response); }, function (xhrError) { e(xhrError); }); }, function (joinError) { e(joinError); }); }); }); }
Usage example :
var url = "http://testServer/FileUpload/OCR/"; var formValues = []; formValues.push({ Token: "1234567890" }); uploadMultipleImages(url, formValues).then(function (response) { var result = response.responseText; //DO STUFF });
Note : It's important to include the third parameter when appending blob data:
var blob = MSApp.createBlobFromRandomAccessStream("image/jpg", data[i]); dataToSend.append(files[i].name, blob, files[i].name);This will result in following HTTP POST:
-----------------------------multipart-form-data-boundary Content-Disposition: form-data; name="File1.JPG"; filename="File1.JPG" Content-Type: image/jpg; --image binary--If the third parameter is skipped: formData.append(objName, objValue); then the filename property will be set to "blob" as below which is not accepted in many server implementations:
-----------------------------multipart-form-data-boundary Content-Disposition: form-data; name="File1.JPG"; filename="blob" Content-Type: image/jpg; --image binary--