Nodejs загружает изображение base64 в хранилище больших двоичных объектов Azure, используя .createBlockBlobFromLocalFile().

Я хочу загрузить изображение профиля пользователя, отправленное из веб-приложения и мобильного приложения через форму Base64.

В запросе POST им нужно отправить JSON тело, которое выглядит примерно так.

{
    "name":"profile-pic-123.jpg",
    "file":"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxQTEhIUEhIUFBUV…K9rk8hCAEkjFMUYiEAI+nHIpsQh0AkisDYRTOiCAbWVtgCtI6IlkHh7LDTQXLH0EIQBj//2Q==" // the base64 image
}

Теперь на стороне сервера, используя Node и Express, я использовал этот модуль npm под названием azure-storage, который предлагает удобный способ загрузки файлов в хранилище BLOB-объектов Azure с помощью веб-службы.

Но есть что-то, что я не могу понять в этом. Вот часть кода моего контроллера. Я успешно создал все необходимые соединения и ключи и еще много чего для создания рабочего blobService :

controllers.upload = function(req, res, next){

    // ...
    // generated some sastoken up here
    // etc.
    // ...

    var uploadOptions = {
        container: 'mycontainer',
        blob: req.body.name, // im not sure about this
        path: req.body.file // im not sure about this either
    }

    sharedBlobService.createBlockBlobFromLocalFile(uploadOptions.container, uploadOptions.blob, uploadOptions.path, function(error, result, response) {
        if (error) {
            res.send(error);
        }
        console.log("result", result);
        console.log("response", response);
    });
}

Я получаю эту ошибку:

{
    "errno": 34,
    "code": "ENOENT",
    "path": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAIAAAB..."
}

person CENT1PEDE    schedule 18.03.2016    source источник


Ответы (2)


В этом случае не следует использовать createBlockBlobFromLocalFile. Вместо этого вы должны использовать createBlockBlobFromText, потому что вы загружаете не локальный файл, а контент в теле запроса.

Вот код:

var uploadOptions = {
    container: 'mycontainer',
    blob: req.body.name, 
    text: req.body.file 
}

sharedBlobService.createBlockBlobFromText(uploadOptions.container, 
                                           uploadOptions.blob, 
                                           uploadOptions.text, 
                      {
                         contentType: 'image/jpeg',
                         contentEncoding: 'base64'
                      }, 
                      function(error, result, response) {
                           if (error) {
                               res.send(error);
                           }
                           console.log("result", result);
                           console.log("response", response);
                      });

blob — это просто имя файла, в данном случае это «profile-pic-123.jpg», а path — это локальный путь к вашему файлу. Поскольку вы не сохраняете файл локально на стороне сервера, path в этом случае не имеет смысла.

Если вам нужна дополнительная информация о хранилище, см. это и это

person Jack Zeng    schedule 18.03.2016
comment
Будет ли это загружать фактическое изображение в хранилище больших двоичных объектов Azure? Скажем, если я перейду к https://myblob.blob.azure.something.net/mycontainer/theimageiuploaded.jpg, я получу визуальное изображение или только текстовую форму? - person CENT1PEDE; 18.03.2016
comment
в этом случае это должно быть https://myblob.blob.core.windows.net/mycontainer/profile-pic-123.jpg. Если ваш контейнер является общедоступным, вы можете получить каталог изображений по этому URL-адресу. Если это частное, вам нужна авторизация, чтобы получить изображение. - person Jack Zeng; 18.03.2016
comment
Я использовал этот код, теперь я получаю эту ошибку {code: ResourceNotFound, statusCode: 404, requestId: bc789061-0001-0022-37f3-80a7c8000000} - person CENT1PEDE; 18.03.2016
comment
Убедитесь, что вы уже создали контейнер в своей учетной записи хранения. Используйте sharedBlobService.createContainerIfNotExists('mycontainer', function(error, result, response){if(!error){}}); для создания контейнера - person Jack Zeng; 18.03.2016
comment
Я уверен, что контейнер существует. :/ - person CENT1PEDE; 18.03.2016
comment
Мне нечего сказать. Я проверил свой код, и он работает для меня. пожалуйста, скопируйте sharedBlobService.createContainerIfNotExists('mycontainer', function(error, result, response){if(!error){}}); в свой код перед sharedBlobService.createBlockBlobFromText и проверьте его снова. - person Jack Zeng; 18.03.2016
comment
Я уже протестировал createContainerIfNotExists(), и он работает. Кстати, изображение, которое я загружаю сейчас, имеет этот формат data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxQTEhIUEhIUFBUV…K9rk8hCAEkjFMUYiEAI+nHIpsQh0AkisDYRTOiCAbWVtgCtI6IlkHh7LDTQXLH0EIQBj//2Q== Но я все еще получаю сообщение об ошибке ResourceNotFound - person CENT1PEDE; 18.03.2016
comment
Для этой части вам нужно установить заголовок Content-Type как «image/jpeg», а Content-Encoding как «base64». Пожалуйста, прочитайте 2 ссылки, которые я предоставил в ответе, и просмотрите учебник. После этого у вас будет базовое представление о службе хранилища Azure. - person Jack Zeng; 18.03.2016
comment
Существует createWriteStreamToBlockBlob, который должен быть полезен в вашем случае. - person Jack Zeng; 18.03.2016
comment
Что делает этот createWriteStreamToBlockBlob? Я попробую. Спасибо! - person CENT1PEDE; 18.03.2016
comment
После использования createWriteStreamToBlockBlob время запроса просто истекло без какого-либо обратного вызова, даже ошибки или аргумента ответа. - person CENT1PEDE; 18.03.2016
comment
О, чувак, пожалуйста, прочитай ссылки, createWriteStreamToBlockBlob использует канальный поток. не как createBlockBlobFromLocalFile или createBlockBlobFromText - person Jack Zeng; 18.03.2016
comment
Та же ошибка. Ресурс не найден. Боже, это уже смешно xD - person CENT1PEDE; 18.03.2016
comment
Кстати, вот полный код, я разместил еще один вопрос по этому поводу -resourcenotfound?noredirect=1#comment59806807_36080854" title="nodejs загружает изображение base64 в хранилище BLOB-объектов Azure, результаты в resourcenotfound">stackoverflow.com/questions/36080854/ - person CENT1PEDE; 18.03.2016
comment
Я прочитал ваш новый вопрос. @MineTanrinianDemir-MSFT дает правильный ответ. - person Jack Zeng; 21.03.2016
comment
Приведенный выше фрагмент кода работает хорошо для меня, но каждый раз, когда я загружаю изображение в лазурный BLOB-объект, я получаю тип содержимого: application/octet-stream. Как установить тип содержимого как изображение/png или изображение/jpg?? - person Dhara Parmar; 04.02.2021

если вы используете javascript sdk v12, вы можете использовать этот пример кода. Это так просто. У меня это реализовано в функции, и она отлично работает, когда все, что мне нужно, это вызвать событие HTTP.

index.js

 const file = await require('./file')();
    uploadOptions = {
        container: 'mycontainer',
        blob: req.body.name, 
        text: req.body.file 
    }

      const fileUploader = await file(uploadOptions.text, uploadOptions.blob, 

uploadOptions.container);

Вы можете использовать отдельный модуль для своей логики и вызывать его из index.js выше.

файл.js

    const { BlobServiceClient } = require("@azure/storage-blob");
    const blobServiceClient = BlobServiceClient.fromConnectionString(process.env.AZURE_STORAGE_CONNECTION_STRING);
const Promise = require('bluebird');

    module.exports = Promise.method(async function() {

        return async function (data, fileName, container) {
            const containerClient = await blobServiceClient.getContainerClient(container);
            const blockBlobClient = containerClient.getBlockBlobClient(fileName);
            const matches = data.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
            const buffer = new Buffer(matches[2], 'base64');

            return await blockBlobClient.upload(buffer, buffer.byteLength );
        };
    });
person Ahmed Elsharif    schedule 29.03.2020