Загрузить файл изображения в sharepoint через API Graph

Я пытаюсь загрузить файл изображения из моего приложения node.js на диск группы в Sharepoint.

Как указано в официальная документация, я делаю запрос следующим образом:

PUT /groups/{group-id}/drive/items/{parent-id}:/{filename}:/content

С двоичным изображением в теле: «Содержимое тела запроса должно быть двоичным потоком загружаемого файла».

Проблема в том, что изображение загружается, но в виде поврежденного файла. Я пробовал разные решения и до сих пор не понимаю, почему изображение всегда повреждено.

Вот мой код:

//i get my image from a URL first
https.get(url.parse(attachment.contentUrl), function (response) {
    var data = [];
    response.on('data', function (chunk) {
        data.push(chunk);
    });
    response.on('end', function () {
      if (response.statusCode === 200) {
        var buffer = Buffer.concat(data);
        //store my image in a local file to test if image is correct (which it is)
        fs.writeFile(localFileName, buffer, (fsError) => {
            //error handling
        });
        functions.uploadImageToSharepoint(session, localFileName, buffer, 
            function (err, body, res) {
                if (err) {
                    console.error(err);
                }else{
                    console.info('OK!');
                }
            });
      } else {
        //error handling
      }
    });
}).on('error', function (e) {
    console.info("error2: " + e);
});

//and the request to graph api
function uploadImageToSharepoint(session, fileName, data, callback) {
  var options = {
    url: 'https://graph.microsoft.com/v1.0/groups/xxxxxxx/drive/root:/yyyyyy/fileName.jpg:/content', 
    method: 'PUT',
    body: data,
    json: true,
    headers: {
      'Content-Type': 'image/jpg',
      Authorization: 'Bearer ' + session.userData.accessToken
    }    
  };

  request(options, function (err, res, body) {
    if (err) return callback(err, body, res);
    if (parseInt(res.statusCode / 100, 10) !== 2) {
        if (body.error) {
            return callback(new Error(res.statusCode + ': ' + (body.error.message || body.error)), body, res);
        }
        return callback(err, body, res);
    }
    callback(err, body ,res);   
  });  
}

localFileName тоже коррумпирован?

Marc LaFleur 30.04.2019 21:08

Локальные файлы сохранились корректно, проблема была в параметре json:true, все равно спасибо :)

jbeltran 03.05.2019 18:03
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
1 539
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Скорее всего, файл поврежден из-за следующего параметра запроса:

var options = {
    json: true,   //<--setting this option sets body to JSON representation of value
    //another properties are omitted for clarity
  };

В этом случае requestустанавливает тело в JSON-представление значения и добавляет accept заголовок к application/json для Upload конечная точка, и двоичный файл будет поврежден.

Решением было бы исключить вариант json из запроса и использовать только правильный content-type:

var options = {
    url: '/me/drive/root:/filename.jpg:/content', 
    method: 'PUT',
    body: data,
    headers: {
      'Content-Type': 'image/jpg',
      Authorization: 'Bearer ' + accessToken
    }    
};

Вот и все! Я несколько дней боролся с потоками и буферами, и проблема была в самом запросе... Спасибо @Вадим Гремячев

jbeltran 03.05.2019 18:02

Удивительно, как трудно найти это решение. Я искал усеченные загрузки вместо поврежденных загрузок. Это помогло!

St.G 21.09.2021 06:46

Другие вопросы по теме