SAPUI5 upload file and use it as model - file-upload

I would like to upload a xml file from the local workspace and use it as model. I can upload files to the server but i don't know how to retrieve the data from the uploaded object and set or load it to my model
Here is how I m uploading the file.
jQuery.ajax({
url: oFileUploader.getUploadUrl(),
headers: oHeaders,
type: 'PUT',
cache: false,
contentType: false,
processData: false,
data: file
});
}
I could not use the standard oFileUploader.upload() because it uses the http method "POST" and I wanted to do a "PUT"
Thank you

It is not clear how you get the contents of the file variable that you are passing to the jQuery.ajax call. Depending on this, you have three options hat come to mind:
Directly use the file variable contents in a model.
Use the FileReader API to read the file contents and put them in a model.
Make the back-end service return the XML content of the file as a response to the AJAX call and then store the response in a model.

Related

Cypress Blob gives error Failed to execute 'atob' on 'Window', with mkv file

I need to test API, with a MKV file in the request.
I use the following code for that:
cy.fixture('video.mkv').then(file => {
const blob = Cypress.Blob.base64StringToBlob(file, "video/x-matroska")
cy.request({
method: ...
url: ...
body: blob,
})
});
Finally, I have this error:
"InvalidCharacterError
Failed to execute 'atob' on 'Window': The string to be decoded contains characters outside of the Latin1 range."
I'm not sure that, for MKV file, I should convert base64 strings to Blob objects.
FYI: I test with Cypress v10.0.0
Can you help me, please?
I think you are looking for arrayBufferToBlob
cy.fixture('video.mkv').then(file => {
const blob = Cypress.Blob.arrayBufferToBlob(file, "video/x-matroska")
cy.request({...
})
These are the available Blob functions, and arrayBufferToBlob looks likely (at least, no errors).
Try out other methods if no-go on this one.
In fact, with a MKV file, it appears that I don't need to convert to blob object, as the request is well sent with this file:
cy.fixture('video.mkv').then(file => {
cy.request({
method: ...
url: ...
body: **file**,
})
});
However, the video is always damaged after the request.
Here are file content for comparison, before and after:
Original content:
Output content:
We can see that a part was modified, like 'A3' at the beginning, replaced by 'EF BF BD'
Note that this service works fine, ouside Cypress, and we are able to retrieve output video.

Handling multipart/form-data on API Gateway/Lambda

I tried few methods, not able to get it working.
Client side(React), I am sending a zip file as follows using POST,
const data = new FormData();
data.append('file', file);
data.append('filename', file.name);
let params = {
headers: {
'Content-Type': 'multipart/form-data'
},
body: data
};
Server side:(API Gateway/Lambda/Nodejs)
I added 'multipart/form-data' to Binary Media Type on Gateway side.
When parsing through lambda event.body is not well formed.
It looks like this:
{"body": "e30=",
"isBase64Encoded": true }
Any ideas what might be happening? Any takes on how to parse?
Although Ariz's answer is correct, I strongly recommend you to look into AWS Pre-Signed Upload URLs. It allows your clients to upload the file first to an AWS S3 Bucket, from where your lambda function can later access the object.
Especially when you're working with large binary files, the former approach can lead to a lot of problems (-> memory issues, which is sparse in Lambda).
I have written a short blog post about this in the past.
you are getting base64 encoded data, following is one of the ways to decode.
However it's an empty object.
var base64 = 'e30='
var decodedData = Buffer.from(base64, 'base64').toString();
console.log(decodedData)

Uploading file to BrickFTP using Dropzone

I have been trying to implement file upload to BrickFTP using Dropzone, but the uploaded file won't open because it contains the WebKitFormBoundary at the top of the file content.
I'm putting method as PUT in Dropzone configuration as per BrickFTP's documentation. BrickFTP uses Amazon S3 so the files are actually being uploaded to S3. I did everything as per their documentation, and everything worked except this last problem I'm having with those extra information at the top of the uploaded file content.
Here is the Coffeescript code responsible for file upload:
brickFTPData = {}
# As per BrickFTP docs, step 1 is
# to get the dedicated upload url for each file by sending a
# request to REST API to indicate intent to upload a file
getUploadUri = (file) ->
result = ""
$.ajax
url : '/a/portal-dev/get-api-keys'
type : 'POST'
dataType : 'json'
data : { file_name: file.name }
async : false
success : (data, textStatus, jqXHR) ->
brickFTPData[file.upload.uuid] =
file_name : file.name
upload_uri : data.upload_uri
ref : data.ref
result = data.upload_uri
return result
# 3rd step is to notify the REST API that the file upload is complete.
finishUpload = (file) ->
$.ajax
url : '/a/portal-dev/upload-done'
type : 'POST'
dataType : 'json'
data :
ref : brickFTPData[file.upload.uuid].ref
file_name : brickFTPData[file.upload.uuid].file_name
success : (data) ->
delete brickFTPData[file.upload.uuid]
console.log data.status
# 2nd step is to upload the file
sampleQuoteDropzone = new Dropzone "#sampleQuoteDropzone",
url : '/demo'
method : 'PUT'
headers : {"Content-Type": "application/octet-stream"}
success : (file, request) ->
finishUpload(file)
sampleQuoteDropzone.on 'processing', (file) ->
upload_uri = getUploadUri(file)
sampleQuoteDropzone.options.url = upload_uri
Upload works fine using the above code but as said when I open the uploaded file into a text editor it starts with following code:
------WebKitFormBoundaryw4bIakMBbkp7ES2E
Content-Disposition: form-data; name="file"; filename="IMG_5652.jpg"
Content-Type: image/jpeg
If I delete these lines and save the file it will work.
But this problem is not seen when uploading file using a regular ajax call outside Dropzone. Following is the working code:
$.ajax
url: data.upload_uri
type: 'PUT'
contentType: 'application/octet-stream'
data: file
processData: false
success: (response) ->
finishUpload(file, data)
Can anyone please advise how to solve this problem?
I solved the problem with following code:
sampleQuoteDropzone.on 'sending', (data, xhr, formData) ->
_send = xhr.send
xhr.send = ->
_send.call(xhr, data)
This solution was actually found here. I saw this before posting this question here, but wasn't sure if this is the right problem/solution. I contacted BrickFTP and they responded fairly quickly saying this solution may work for me, and yes it certainly does.

File upload checking REAL file mime type when uploading directly to S3

I'm using DropzoneJS to upload files directly to S3. When they add I file I am using my backend to check the mime type and create the S3 signature. When I say adding I file, I just means it's added it to the Dropzone queue so the file isn't uploaded yet it's just sending metadata about the file to the /upload/sign url.
this.on('addedfile', function (file) {
$.get('/upload/sign', {
name: file.name,
size: file.size,
type: file.type,
}).done(function (response) {
myDropzone.options.url = response.attributes.action;
file.additionalData = response.additionalData;
myDropzone.processFile(file);
}).fail(function (response) {
var data = JSON.parse(response.responseText);
myDropzone.emit('error', file, data);
});
});
This is all good! The problem is the file's mime type is only determined by the file extension, so I can happily rename a file from image.jpg to image.mp3 and file.type will be audio/mp3. This I guess is fine for browser warnings, but not if I want that mp3 to play or if I eventually want to process the audio!
Is there any way of telling the REAL mime type of the file, without having to pass the upload directly to the servers file system? I need to upload directly to S3 so passing it through an EC2 is not an option.

Sending binary data using multipart/form-data from a worker with IE11

I'm trying to send a multipart/form-data from a worker with IE. I've already done it with Chrome, Firefox, Safari using formData objects (not supported IE, I need a manual one)
The binary data I'm sending is a crypto-js encrypted data. With formData objects I do:
var enc = new Buffer(encrypted.ciphertext.toString(CryptoJS.enc.Base64), 'base64');
formData.append("userFile" , new Blob([finalEncrypted], {type: 'application/octet-binary'}), 'encrypted')
this works fine generating a multipart like this(missed some parts of it):
request headers:
Accept:*/*
Accept-Encoding:gzip, deflate
Cache-Control:no-cache
Connection:keep-alive
Content-Length:30194
Content-Type:multipart/form-data; boundary=WebKitFormBoundary0.gjepwugw5cy58kt9
body:
--WebKitFormBoundary0.gjepwugw5cy58kt9
Content-Disposition: form-data; name="userFile"; filename="encrypted"
Content-Type: binary
all binary data
--WebKitFormBoundary0.cpe3c80eodgc766r--
With the manual multipart/form-data:
IE11 doesn't accept readAsBinaryString(deprecated)
I would like to avoid sending base64 encoded data(readAsDataURL)(33% payload)
The binary data I'm sending is a crypto-js encrypted data.
I'm trying:
finalEncrypted = new Buffer(encrypted.ciphertext.toString(CryptoJS.enc.Base64), 'base64');
then in my manual multipart I tried to convert the buffer to a binary string:
item.toString('binary')
the multipart result looks looks this:
--WebKitFormBoundary642013568702052
Content-Disposition: form-data; name="userfile"; filename="encrypted"
Content-Type: binary
all binary data
ÐçÀôpRö3§]g7,UOÂmR¤¼ÚS"Ê÷UcíMÆÎÚà/,hy¼øsËÂú#WcGvºÆÞ²i¨¬Ç~÷®}éá?'é·J]þ3«áEÁÞ,4üBçðºÇª bUÈú4
T\Ãõ=òEnýR _[1J\O-ïǹ C¨\Ûøü^%éÓÁóJNÓï¹LsXâx>\aÁV×Þ^÷·{|­'
On the .NET server we check the hash calculated on client versus calculated on server. Server reply that hashes doesn't match. This makes me think that I'm not sending the file correctly.
It looks like you did not yet get a solution, at least you did not post it here if you had one.
On my end I use jQuery which handles the low level nitty gritty of the actual post.
It may be that you are doing one small thing wrong and IE fails on it. Since you do not show what you used with FormData. It is rather difficult to see whether you had a mistake in there.
// step 1. setup POST data
var data = new FormData();
data.append("some_variable_name", "value_for_that_variable");
data.append("some_blob_var_name", my_blob);
data.append("some_file_var_name", my_file);
// step 2. options
var ajax_options =
{
method: "POST",
processData: false,
data: data,
contentType: false,
error: function(jqxhr, result_status, error_msg)
{
// react on errors
},
success: function(data, result_status, jqxhr)
{
// react on success
},
complete: function(jqxhr, result_status)
{
// react on completion (after error/success callbacks)
},
dataType: "xml" // server is expected to return XML only
};
// step 3. send
jQuery.ajax(uri, ajax_options);
Step 1.
Create a FormData object and fills the form data, that includes variables and files. You may even add blobs (JavaScript objects, will be transformed to JSON if I'm correct.)
Step 2.
Create an ajax_options object to your liking. Although here I show your the method, processData, data, contentType as they must be in case you want to send a FormData. At least, that works for me... It may be possible to change some of those values.
The dataType should be set to whatever type you expect in return.
Step 3.
Send the request using the ajax() function from the jQuery library. It will build the proper header and results as required for the client's browser.