on 2013 Jul 04 3:17 PM
Hi,
I have a SAPUI5 FileUploader that should post the file to a (NetWeaver Gateway) OData service - which requires that the request has an X-CSRF token. How can I make this happen?
Currently, prior to starting the upload I already did a refreshSecurityToken() on the OData model. But the FileUploader does not pick up this value. How can I proceed here?
Thank you for your help!
Hi Daniel
Further to the suggestion i made in http://scn.sap.com/thread/3383994 that I didn't think this was possible with the FileUploader control, I found some time today to investigate further.
I tried to use a proxy to set the http headers like Jibin Joy suggested in http://scn.sap.com/thread/3262540 the issue like he found was that the data that is posted is encoded as multipart/form-data and the Gateway service is expecting a media resource with the correct content type eg image/gif.
I managed to get the FileLoader control posting successfully to Gateway services by extending the control, replacing the form.submit with an AJAX call.
sap.ui.commons.FileUploader.extend("ODataFileLoader", {
...
upload : function() {
...
var file = jQuery.sap.domById("upload_1-fu").files[0];
var oRequest = sap.ui.getCore().getModel(this.getModelName())._createRequest();
var oHeaders = {
"x-csrf-token": oRequest.headers['x-csrf-token'],
"slug": this.getSlug(),
};
jQuery.ajax({
type: 'POST',
url: this.getUploadUrl(),
headers: oHeaders,
cache: false,
contentType: false,
processData: false,
data: file,
success: _handleSuccess,
error: _handleError
});
The code gets the CSRF token from a nominated Model and uses this with a Slug header that can be dynamically set.
You can find a working example at https://github.com/jasper07/sapui5bin/blob/master/ODataFileUpload.html
Cheers
John P
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Daniel
I didn't have the issue with domById running in IE9, the issue i did get was IE expects the contentType to be set in the jQuery Ajax call, i updated the code so it took the content type from the file, may need a better solution for this comparing file and file extension etc.
https://github.com/jasper07/sapui5bin/blob/master/ODataFileUpload.html
HtH
John P
Hi John,
the issue is not with the domById, but with the .files. I modified the code a little to demonstrate:
var file_imput = jQuery.sap.domById(this.getId() + "-fu");
console.log(file_imput); // -> [object HTMLInputElement]
console.log(file_imput.files); // -> undefined
console.log(file_imput.files[0]); //-> also undefined
var file = file_imput.files[0]; // -> undefined
Do you have any extensions installed that make it work for you? Or might I have some to strict security issues that prevent my IE9 from working with your code (though I tested on two maschines)?
Thanks and reagrds,
Daniel
Hi Daniel,
on IE9 it not gonna work. Because IE9 not support File/FileReader (moderner Browser needed )
Below is the explanation and a workaround solution.
http://stackoverflow.com/questions/15664069/create-file-upload-that-work-in-ie
the plugin mentioned in the following post could also help you
http://stackoverflow.com/questions/6191792/javascript-file-upload
Or let's just use Chrome or Firefox
Regards,
Hai
Hi John,
We are trying approve the workflow decision by POST the HTTP request with Headers (SAP Business Workflow with SAP NetWeaver Gateway version 7.4).
HTTP POST with Headers (x-csrf-token)
we are following the SAP document http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/509c922a-aa9a-2f10-328c-d3814560d...
Below the code we are trying the same.
var oHeaders = {};
oHeaders["x-csrf-token"] = "<?php echo $csrftoken['xcsrfToken'];?>";
oHeaders["Authorization"] = "Basic ZGV2ZWxvcGVyOm5vc2VjcmV0";
jQuery.ajax({
type: "POST",
data: null,
headers: oHeaders,
success: successFunc,
error: errorFuncDefault
});
function successFunc(data) {
alert(data);
}
function errorFuncDefault(data) {
alert(data + 'error');
}
We facing the below errors like Method not supported some time and Authorization failed and we tried all possible ways but no result.
Could please help me, where we are going wrong.
Thanks in advances
Venky.
Hi Hai,
Thanks for you tips. Unfortunately they don't work for us.
We need to support IE9, using SAPUI5 and NetWeaver Gateway. Our upload service requires 2 header parameters, which are slug and the X-CSRF. All is possible with using ajax request as stated above and works in chrome and firefox etcetera, but not in IE9. Your tips are usefull and will work with for example using an iframe (since the fileAPI is not there yet in IE9). However, we need to be able to add the headers which is not possible for an iframe. We researched also using the XHR request, but also here adding the headers doesn't work in IE9. Would you probably have other suggestions?
Unfortunately using an other browser is not an option.
Thanks!
Wim
Hi Wim,
only browsers with support for XHR file upload support setting custom headers! Unfortunatel, XHR (XMLHttpRequest) file uploads is only supported from IE 10+ on. In other words: setting HTTP headers for a file upload request will not work in IE8 and IE9. I had the same issue but with IE8.
I guess you have to create some other RESTful service for the file upload outside of the Gateway. I would be glad if the SAP Gateway team would offer some information and a workaround for IE8/IE9 users!
Cheers,
Nabi
Hi Nabi,
Thanks for your answer. We had the same findings indeed.
We managed to fix it. Since we're already having a java server for proxying in between, we managed to fix it over there. Solution: send parameters in the url, and use the servlet to add the header parameters based on the url parameters. The servlet already had the functionality of proxying but now also use it, to add the proper headers for slug and x-csrf/ x-requested-with header. This works and does add the file in the backend. However, since IE9 sends the file via an iframe as multipart/form data, it has extra header and footer data in the file in the backend. These need to be cut off in the backend ECC system. This functionality works smoothly now for IE9.
Cheers,
Wim
Hi John,
I have tried the below code. It seems to send data to the url but fails at rendering.
<script type="text/javascript">
jQuery.sap.declare("MyFileUploader");
jQuery.sap.require("sap.ui.commons.FileUploader");
sap.ui.commons.FileUploader.extend("MyFileUploader", {
upload : function() {
var token;
token = fetch_XCSRF_Token();
var oHeaders = {
"x-csrf-token": token,
};
var file = jQuery.sap.domById(this.getId() + "-fu").files[0];
try {
if (file) {
this._bUploading = true;
var that = this;
var _handleSuccess = function(data){
that.fireUploadComplete({"response": "Success: File uploaded to entity" });
that._bUploading = false;
};
var _handleError = function(data){
var errorMsg = '';
if (data.responseText[1]){
errorMsg = /<message>(.*?)<\/message>/.exec(data.responseText)[1];
}else{
errorMsg = 'Something bad happened';
}
that.fireUploadComplete({"response": "Error: " + errorMsg});
that._bUploading = false;
};
jQuery.ajax({
type: 'POST',
url: this.getUploadUrl(),
headers: oHeaders,
cache: false,
contentType: file.type,
processData: false,
data: file,
success: _handleSuccess,
error: _handleError
});
jQuery.sap.log.info("File uploading to " + this.getUploadUrl());
}
} catch(oException) {
jQuery.sap.log.error("File upload failed:\n" + oException.message);
}
},
renderer :{
}
});
Hi Prabaharan,
I am working on a project which we have to support file upload in IE8 and IE9, we are also using the unified FileUploader control and we faced the same problem with the x-csrf token check on gateway using IE8 and IE9. We are able to solve this problem by creating a custom request handler. Here is our solution:
Client side (UI5 ver 1.22.4)
-----------------
- In the UI5 client, for IE8 and IE9, add the x-csrf-token and slug (if you need it) value as hidden input value to the upload form. For newer browser (Chrome, IE10 etc.) , these values are added to the http request header.
- You can look up how to retrieve the upload form by looking at the upload method implementation for the FileUploader control in UI5 source code.
- For IE8 and IE9, set a different value (external alias defined below) for the uploadurl attribute of the fileuploader control.
Server side
------------------
The problem for IE8 and IE9 is that the default handler class (/IWFND/CL_SODATA_HTTP_HANDLER) for ICF odata node only reads the x-csrf-token from the http header and it's not possible to set http header in IE8 and IE9. The idea is to create a custom handler to read the x-csrf-token from the post data and add it to the http request header and resume the normal request flow.
- Create a new custom handler class that implements the interface IF_HTTP_EXTENSION. This handler will read the x-csrf-token (or whatever name you use for the hidden input field) and set it in the http request header
- Since we cannot modify the handler list for the odata node because it's sap standard, we'll add the custom handler to the handler list in our application node which we have control. Add the default odata handler (/IWFND/CL_SODATA_HTTP_HANDLER) as the next handler in the list.
- Create an external alias for the new custom handler (e.g. customhandler). This value is used as the value for the uploadurl attribute on fileuploader control (pre-pend and append the value with '/', e.g. /customhandler/) before setting to uploadurl attribute.
Summary
-------------------
In IE8 and IE9, the fileuploader uploadurl will point directly to the application node and our custom handler will be processed before the default odata handler. Our custom handler reads the x-csrf-token from the post data and sets it to the http request handler thus allowing the default odata handler to read it.
Best Regards,
Andrew
Hi Adhiamol,
I am using UI5 1.22.4 and I was able to upload files using the FileUploader control without extending the FileUploader control for Chrome, Safari, Firefox and IE10. For IE8 and IE9, UI5 uses form submit instead of XMLHttpRequest and I have to overwrite fileuploader upload method to set csrf token as hidden input values.
var oFileUploader = new sap.ui.unified.FileUploader({
buttonText:i18n('BTN_BROWSE'),
name: 'fileupload',
value: '',
sendXHR: true,
useMultipart: true,
headerParameters: [
new sap.ui.unified.FileUploaderParameter({
name: 'x-csrf-token',
value: app.data.mainModel.getHeaders()['x-csrf-token']
})
],
uploadComplete: function (oEvent) {
log(oEvent.getParameter('response'));
me.handleCreateComplete();
}
});
oFileUploader.setUploadUrl(your gateway service url);
For IE8 and IE9, please read my reply to Prabaharan above.
Thanks,
Andrew
Hi Andrew,
Thanks for the help Andrew. I followed below steps as you suggested but I am experiencing few issues. I am testing from Google Chrome REST client to make sure handler classes are triggered correctly.
Could you throw some lights here?
2.Created an External alias and added the handler. This alias will point to the OData service which will read the attachment.Assigned as shown below.
But when calling the URL only custom handler is getting called and OData service for File upload is not getting triggered.
Issue: URL should be
http://abc.com:8030/sap/opu/odata/sap/ZGW_DEMO_READ_ATTACHMENT_SRV/FileDetailSet/
But the custom handler points only to /default_host/sap/opu/odata/sap/zgw_demo_read_attachment_srv
Entity set name is missing in the above URL.(FileDetailSet) So the runtime interface (shown below) is not getting called.
Could you please tell me how to create alias by mentioning entity set name too?
Please bare me if I am making dumb questions. Thanks.
Regards
Prabaharan Asokan
Hi Andree,
I have followed your idea suggested and wrote this as a separate blog post as this will be useful for the community members. Part 1 covers what we need steps need to be covered in SAP Gateway system.(Link is given above). Hopefully I will write a separate blogs to handle this from SAPUI5 and NON_SAPUI5 web applications.
Regards
Prabaharan
Hello Prabaharan,
I would like to thank you for the detailed blog that you created which tackles the step by step process on how to configure the oData for file uploading in IE9. This approach has been followed on the server side. On the client side I successfully uploaded the file in the oData using the control in SAPUI5 which is the sap.ui.commons.FileUploader. First I fetch the X-csrf-token and then, used this together with the slug in order to form the upload url of the control, passing the token and slug as url parameters.
However I am having an issue in retrieving the response from the server wherein I am getting this error in the Odata Response: “Internet Explorer Cannot Display This Feed”. I think IE9 does not support Atom version 2.0 which is the feed format of the response (IE9 supports only older versions). Did you encounter this issue and have a recommended solution? E.g. is there a server-side configuration that controls the atom version used for the response?
Regards,
Kath
Hi Kathleen,
Good to know it helped you.Thanks for the comment. I am looking to create a solution in UI side and am working on this. I think we need to cut off the extra header and footer in the request and remove the file content before sending the response to caller interface(app).
Since novice to UI5 i am consuming a bit of time on this. I would appreciate your help on this if you could share me the code snippet (client side) to upload the file . Let me know your thoughts. Thanks
Regards
Prabaharan Asokan
Hi Andrew,
I am looking to create a solution in UI side suggested by you and am working on this.Since novice to UI5 i am consuming a bit of time on this. I would appreciate your help on this if you could share me the code snippet (client side) to upload the file . Let me know your thoughts. Thanks
Regards
Prabaharan Asokan
Hi Prabaharan,
Here are the code snippets in reference to my original description for the changes needed to be made on the client side based on UI5 version 1.22.4.
*It's possible that additional changes/updates are required for the code snippets to be compatible/work in newer version of UI5.
Client side (UI5 ver 1.22.4)
-----------------
- In the UI5 client, for IE8 and IE9, add the x-csrf-token and slug (if you need it) value as hidden input value to the upload form. For newer browser (Chrome, IE10 etc.) , these values are added to the http request header.
Override the function sap.ui.unified.FileUploader.prototype.upload. Since we want to keep the existing implementation for non IE8 and non IE9 browsers, the changes we add should only apply to IE8 and IE9. In this function, there should already be a check for 'window.File'. We'll add the following code to set the header parameters as hidden input fields to the form when 'window.File' returns false.
if (this.getSendXHR() && window.File) {
....
}
else {
if (sap.ui.Device.browser.msie && (sap.ui.Device.browser.version==8 || sap.ui.Device.browser.version==9)) {
if (this.getHeaderParameters()) {
var oHeaderParams = this.getHeaderParameters();
for (var i = 0; i < oHeaderParams.length; i++) {
var sHeader = oHeaderParams[i].getName();
var sValue = oHeaderParams[i].getValue();
if(sHeader=='x-csrf-token' || sHeader=='slug'){
var el = document.createElement('input');
el.type = 'hidden';
el.name = sHeader;
el.value = sValue;
uploadForm.appendChild(el);
}
}
}
}
uploadForm.submit();
}
- You can look up how to retrieve the upload form by looking at the upload method implementation for the FileUploader control in UI5 source code.
The uploadForm should already be available in the overridden method (see above).
- For IE8 and IE9, set a different value (external alias defined below) for the uploadurl attribute of the fileuploader control.
// Call updateSecurityToken() from your model
var oFileUploader = new sap.ui.unified.FileUploader({
...
sendXHR: true,
useMultipart: true,
headerParameters: [
new sap.ui.unified.FileUploaderParameter({
name: 'x-csrf-token',
value: your csrf token value
}),
// if you need 'slug'
new sap.ui.unified.FileUploaderParameter({
name: 'slug',
value: your slug value
})
]
})
oFileUploader.setUploadUrl(url);
// For IE8 and IE9, the url value would be the external alias of your custom handler
// For all other browser, it will be your default service url for file upload
Thanks,
Andrew
User | Count |
---|---|
69 | |
13 | |
11 | |
10 | |
9 | |
9 | |
6 | |
6 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.