Blob JavaScript в FormData с помощью мобильного приложения SAPUI5 - PullRequest
0 голосов
/ 08 октября 2018

Я знаю, что есть несколько тем на эту тему, но я не смог определить проблему в моем случае.

У меня есть приложение, в котором я загружаю изображение в URL-адрес конечной точки и после обработкиЯ получу ответ.Пока работает нормально.Файл содержится в объекте formdata при использовании FileUploader-Control из SAPUI5.

При переключении с загрузки файла на «фотографирование с помощью камеры смартфона» у меня нет файла, у меня есть dataurl base64 (XString) объект изображения.

var oImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAA…8ryQAbwUjsV5VUaAX/y+YSPJii2Z9GAAAAABJRU5ErkJggg=="} // some lines are missing > 1 million lines

Я думал, что преобразование его в BLOB-объект и добавление его в FormData может быть решением, но оно не работает вообще.

var blob = this.toBlob(oImage)
console.log("Blob", blob); // --> Blob(857809) {size: 857809, type: "image/png"} size: 857809 type: "image/png" __proto__: Blob 

var formData = new window.FormData();
formData.append("files", blob, "test.png");
console.log("FormData", formData); // seems empty --> FormData {}__proto__: FormData

Функции (работаетотлично с моей точки зрения)

toBlob: function dataURItoBlob(dataURI) {
        var byteString = atob(dataURI.split(',')[1]);
        var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
        var ab = new ArrayBuffer(byteString.length);
        var ia = new Uint8Array(ab);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
        var bb = new Blob([ab], {
            "type": mimeString
        });
        return bb;
},

Это моя проблема, FormData пуст и мой POST-запрос выдает неопределенную ошибку (Ошибка загрузки данных: TypeError: Невозможно прочитать свойство 'status' undefined в конструкторе.eval (... m / resources / sap / ui / core / library-preload.js? eval: 2183: 566))

//Create JSON Model with URL
var oModel = new sap.ui.model.json.JSONModel();
var sHeaders = {
    "content-type": "multipart/form-data; boundary=---011000010111000001101001",
    "APIKey": "<<myKey>>"
};

var oData = {
    formData
};

oModel.loadData("/my-destination/service", oData, true, "POST", null, false, sHeaders);

oModel.attachRequestCompleted(function (oEvent) {
    var oData = oEvent.getSource().oData;
    console.log("Final Response XHR: ", oData);
});

Спасибо за любую подсказку

1 Ответ

0 голосов
/ 09 октября 2018

загружаемая коллекция - это сложный стандартный элемент управления, который можно использовать для управления вложениями.На рабочем столе открывается диалоговое окно файла, на мобильном устройстве - параметры фотографии ios или android, что означает выбор фотографии с рулона камеры или создание новой фотографии.

Довольно простой пример, включая URL загрузки и другие обработчики, которые вам понадобятся.Доступно больше опций, настройте их в соответствии с вашими потребностями.В вашем XML:

<UploadCollection 
    uploadUrl="{path:'Key',formatter:'.headerUrl'}/Attachments" 
    items="{Attachments}" 
    change="onAttachUploadChange" 
    fileDeleted="onAttachDelete" 
    uploadEnabled="true"
    uploadComplete="onAttachUploadComplete">
    <UploadCollectionItem 
        documentId="{DocID}"
        contributor="{CreatedBy}" 
        fileName="{ComponentName}" 
        fileSize="{path:'ComponentSize',formatter:'.formatter.parseFloat'}" 
        mimeType="{MIMEType}" 
        thumbnailUrl="{parts:[{path:'MIMEType'},{path:'DocID'}],formatter:'.thumbnailURL'}" 
        uploadedDate="{path:'CreatedAt', formatter:'.formatter.Date'}" url="{path:'DocID',formatter:'.attachmentURL'}" visibleEdit="false" 
        visibleDelete="true" />
</UploadCollection>

Вот обработчики.Особенно важен onAttachUploadChange.Я должен отметить, что нет явного поста.Если uploadUrl установлен правильно, сообщение все равно будет запущено.

onAttachUploadChange: function(oEvent) {
  var csrf = this.getModel().getSecurityToken();
  var oUploader = oEvent.getSource();
  var fileName = oEvent.getParameter('files')[0].name;
  oUploader.removeAllHeaderParameters();
  oUploader.insertHeaderParameter(new UploadCollectionParameter({
    name: 'x-csrf-token',
    value: csrf
  }));
  oUploader.insertHeaderParameter(new UploadCollectionParameter({
    name: 'Slug',
    value: fileName
  }));
},

onAttachDelete: function(oEvent) {
  var id = oEvent.getParameter('documentId');
  var oModel = this.getModel();

  //set busy indicator maybe?

  oModel.remove(`/Attachments('${encodeURIComponent(id)}')`, {
    success: (odata, response) => {
      //successful removal
      //oModel.refresh();
    },
    error: err => console.log(err)
  });
},

onAttachUploadComplete: function(oEvent) {

  var mParams = oEvent.getParameter('mParameters');
  //handle errors an success in here. Check `mParams`. 
}

как для форматеров, чтобы определить URL, это зависит от ваших настроек.В приведенном ниже случае поток настроен на текущий контекст привязки, и в этом случае это один из способов сделать это.Вам понадобится весь URI, включая биты /sap/opu/... и т.д.

  headerUrl: function() {
    return this.getModel().sServiceUrl + this.getView().getBindingContext().getPath()
  },

URL-адрес для вложений аналогичен, но обычно указывает на сущность самой службы вложений.

  attachmentURL: function(docid) {
    return this.getModel().sServiceUrl + "/Attachments('" + docid + "')/$value";
  },

Вы можете придумать это, чтобы проверить, является ли это изображение, и в этом случае вы можете включить тип пантомимы, чтобы показать миниатюру.

Возможно, есть лучшие способы сделать это, но я нашел это довольно гибким ...

...