Используя Autodesk Forge OSS, я могу загрузить в корзину, но тело загрузки пусто

Я использую службу Autodesk Forge Object Storage Service, и хотя я могу загрузить свой файл в корзину, когда я пытаюсь загрузить его, тело оказывается пустым. Однако при использовании Head размер данных правильный.

Вот моя загрузка (обратите внимание, что я использую API загрузки подписанных URL-адресов):

            var url = uploadOptions.url;

            var fileReader = new FileReader();
            // UploadOptions.Body contains a Blob
            fileReader.readAsBinaryString(uploadOptions.Body);
            fileReader.onloadend = function (e) {
                var xhr = new XMLHttpRequest();
                var lastLoadedValue = 0;
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 201)) {
                        console.log('UPLOAD FINISHED:', xhr.responseText);
                        callback();
                    }
                };
                xhr.open("PUT", url, true);
                xhr.withCredentials = true;
                // uploadOptions.ContentType = 'application/octet-stream'
                xhr.setRequestHeader('Content-Type', uploadOptions.ContentType);
                xhr.send(e.target.result);

Вот моя загрузка:

         superagent
            .get(_autodesk_api_baseurl
                + baseUrl
                + downloadOptions.bucket
                + '/objects/'
                + encodeURIComponent(downloadOptions.key))
            .set('Authorization', 'Bearer '
                + token.access_token)
            .query({'response-content-type': 'application/octet-stream'})
            .end(function (err, resp) {
                if (typeof callback === 'function') {
                    // All works fine
                    callback(undefined, resp);
                }
            });

И затем, в обратном вызове, я печатаю свой ответ, а тело пусто. Я даже написал ответ в формате JSON на файл, чтобы получить это:

{
"req": {
    "method": "GET",
    "url": "https://developer.api.autodesk.com/oss/v2/buckets/storage.vcs.prod.mevsg.autodesk.com/objects/assets%2FNT5NR9KJU2PH%2Fea02ec77505f2ea2defac93fe231764f2916e4d1aeaac7d92945a08a0086c60667369431361d5aa426d4cccca49b9e4c7cb70bc6ebf700258a3cb37617eacfa0"
},
"header": {
    "access-control-allow-credentials": "true",
    "access-control-allow-headers": "Authorization, Accept-Encoding, Range, Content-Type",
    "access-control-allow-methods": "GET",
    "access-control-allow-origin": "*",
    "content-disposition": "attachment; filename=\"ea02ec77505f2ea2defac93fe231764f2916e4d1aeaac7d92945a08a0086c60667369431361d5aa426d4cccca49b9e4c7cb70bc6ebf700258a3cb37617eacfa0\"",
    "content-encoding": "gzip",
    "content-type": "application/octet-stream",
    "date": "Thu, 30 Jun 2016 18:03:10 GMT",
    "etag": "\"8ad9c59b256cef48798a94c0295023088016d43a\"",
    "server": "Apigee Router",
    "vary": "Accept-Encoding",
    "transfer-encoding": "chunked",
    "connection": "Close"
},
"status": 200

}

Как видите, тела нет. Но когда я использую Head для объекта, я получаю нужное количество байтов.

Может кто подскажет, что я делаю не так? Я попытался жестко закодировать Content-Type на application/x-www-form-urlencoded, а затем я смог загрузить файл (в теле были байты), но байты были немного изменены. Например, 208 (11010000) превратилось в 80 (1010000). Как видите, первый бит был перевернут. С этим типом содержимого я не мог открыть файл. Какой способ мне использовать?


ОБНОВЛЕНИЕ: с помощью Augusto я обнаружил проблему.

  1. Superagent, похоже, не работает, но Request работает.
  2. Не уверен, что это повлияло на реальность, но я установил кодировку для загруженного буфера как base64.
  3. Мне нужно было загрузить Blob напрямую. Мне не нужно было использовать FileReader для чтения байтов.

person Jonathan Rainville    schedule 30.06.2016    source источник


Ответы (3)


Вот что решило проблему:

Для загрузки мне нужно было отправить только Blob. Вот обновленный код:

    var url = uploadOptions.url;

    var xhr = new XMLHttpRequest();

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 201)) {
            console.log(xhr.status);
            console.log('UPLOAD FINISHED:', xhr.responseText);
            callback();
        }
    };

    xhr.open("PUT", url, true);
    xhr.withCredentials = true;
    // Send the Blob directly!!
    xhr.setRequestHeader('Content-Type', uploadOptions.ContentType);
    xhr.send(uploadOptions.Body);

Для загрузки библиотека Superagent не работала, но Request работал. Я также изменил кодировку буфера на base64. Вот код:

    request({
        url: _autodesk_api_baseurl
            + baseUrl
            + downloadOptions.bucket
            + '/objects/'
            + encodeURIComponent(downloadOptions.key),
        method: "GET",
        headers: {
            'Authorization': 'Bearer ' + token.access_token
        },
        encoding: null
    }, function (error, response, body) {
        //Error handling goes here

        if (typeof callback === 'function') {
            callback(null, new Buffer(body, 'base64'));
        }
    });

После этого я могу просто записать буфер в файл и открыть его. Спасибо тем, кто помог ответить.

person Jonathan Rainville    schedule 13.07.2016

Этот раздел кажется неправильным:

.query({'response-content-type': 'application/octet-stream'})

Должен быть

.set('response-content-type', 'application/octet-stream')

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

person Gregra    schedule 30.06.2016
comment
Content-type был добавлен позже, когда я не знал, что еще можно исправить. Так что да, я удалю это. - person Jonathan Rainville; 30.06.2016

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

Это завиток для его загрузки, который должен работать:

curl -v "https://developer.api.autodesk.com/oss/v2/buckets/storage.vcs.prod.mevsg.autodesk.com/objects/assets%2FNT5NR9KJU2PH%2Fea02ec77505f2ea2defac93fe231764f2916e4d1aeaac7d92945a08a0086c60667369431361d5aa426d4cccca49b9e4c7cb70bc6ebf700258a3cb37617eacfa0"
  -X GET
  -H "Authorization: Bearer AbCdEfGhIjKlMnOpQrStUvXwYz"

А вот код, который я использовал с модулем NodeJS / Request. На самом деле он довольно общий, но если я передаю ресурс / oss / URL, он работает нормально. Я не уверен, какую библиотеку вы используете, извините.

function download(resource, token, onsuccess) {
    console.log('Downloading ' + config.baseURL + resource); // debug
    request({
        url: config.baseURL + resource,
        method: "GET",
        headers: {
            'Authorization': 'Bearer ' + token,
        },
        encoding: null
    }, function (error, response, body) {
        onsuccess(new Buffer(body, 'base64'));
    });
}
person Augusto Goncalves    schedule 30.06.2016
comment
Да, я могу получить подробную информацию о файле. Я также попытался загрузить с помощью вашего cUrl (мне пришлось сгенерировать новый токен), и я смог правильно загрузить файл. Таким образом, он подтверждает, что файл находится на сервере. И тип содержимого был добавлен позже, когда я пробовал что-нибудь, чтобы заставить его работать, так что это не ответ. Спасибо за ответ. - person Jonathan Rainville; 30.06.2016
comment
Я отредактировал свой ответ кодом, который использую (и работает) - person Augusto Goncalves; 30.06.2016
comment
Я пробовал твой код. Сработало, достаю тело и могу записать в файл. Так что, думаю, проблема возникла только в моей библиотеке или что-то, что не нравится OSS. Но потом я не могу открыть файл. Это файл 3ds Max, и когда я его открываю, появляется сообщение "Ошибка открытия файла". Думаю, это вопрос кодировки. В любом случае, если вы еще не знаете проблему из кода, который там, я попробую, и если я не смогу ее понять, я задам другой вопрос. - person Jonathan Rainville; 12.07.2016
comment
это может быть что-то в кодировке ... Я использую: new Buffer (body, 'base64') - person Augusto Goncalves; 12.07.2016
comment
Еще раз спасибо за вашу помощь, мне удалось найти остальную часть проблемы. Это была моя загрузка. Я отправил байты прочитанными, но мне нужно было отправить только Blob. Теперь все работает :) - person Jonathan Rainville; 13.07.2016
comment
Ницца! если есть время, поделитесь, пожалуйста, решением! люблю голосовать за это! :-) - person Augusto Goncalves; 13.07.2016