需要修复使用Node.js从天蓝色Blob上传和下载图像的代码

时间:2019-01-28 08:46:31

标签: node.js azure express azure-storage-blobs

我正在尝试编写一个nodejs应用程序,该应用程序将图像上传到一个天蓝色的blob,以便另一个程序可以连接到DB并下载图像。

我无法从Blobs api中获取代码。我认为上传工作正常,但是我似乎无法从给定的URL下载图片。

async function execute() {

    const containerName = "a00008";
    const blobName = "myBlob";
    const content = "./sun.png";
    const localFilePath = "./sun.png";

    const credentials = new SharedKeyCredential(STORAGE_ACCOUNT_NAME, ACCOUNT_ACCESS_KEY);
    const pipeline = StorageURL.newPipeline(credentials);
    const serviceURL = new ServiceURL(`https://${STORAGE_ACCOUNT_NAME}.blob.core.windows.net`, pipeline);

    const containerURL = ContainerURL.fromServiceURL(serviceURL, containerName);

    const aborter = Aborter.timeout(30 * ONE_MINUTE);


    await showContainerNames(aborter, serviceURL);

    await containerURL.create(aborter);


    await uploadLocalFile(aborter, containerURL, content);
    console.log(`Local file "${content}" is uploaded`);

    await uploadStream(aborter, containerURL, localFilePath);
    console.log(`Local file "${localFilePath}" is uploaded as a stream`);




    const blockBlobURL = BlockBlobURL.fromContainerURL(containerURL, content);
    console.log("The blobs URL is: " + JSON.stringify(blockBlobURL.url));

    const downloadResponse = await blockBlobURL.download(aborter, 0);
    downloadedContent = downloadResponse.readableStreamBody.read(content.length)
    console.log(`Downloaded blob content: "${downloadedContent}"`);}

    execute().then(() => console.log("Done")).catch((e) => console.log(e));

这是uploadLocalFile和uploadLocalStream的代码,它们直接取自MS azure文档:

async function uploadLocalFile(aborter, containerURL, filePath) {

    filePath = path.resolve(filePath);

    const fileName = path.basename(filePath);
    const blockBlobURL = BlockBlobURL.fromContainerURL(containerURL, fileName);

    return await uploadFileToBlockBlob(aborter, filePath, blockBlobURL);
}

async function uploadStream(aborter, containerURL, filePath) {

    filePath = path.resolve(filePath);

    const fileName = path.basename(filePath).replace('.md', '-stream.md');
    const blockBlobURL = BlockBlobURL.fromContainerURL(containerURL, fileName);

    const stream = fs.createReadStream(filePath, {
      highWaterMark: FOUR_MEGABYTES,
    });

    const uploadOptions = {
        bufferSize: FOUR_MEGABYTES,
        maxBuffers: 5,
    };

    return await uploadStreamToBlockBlob(
                    aborter, 
                    stream, 
                    blockBlobURL, 
                    uploadOptions.bufferSize, 
                    uploadOptions.maxBuffers);
}

我尝试了uploadLocalFile和uploadStream,我将其中的1条注释掉了,然后单独尝试了另一条,不确定哪一个是用于图像的正确选择。

如果我转到blockBlobURL,则会收到错误消息:该XML文件似乎没有与之关联的任何样式信息。文档树如下所示。

当我console.log blob内容时,也会得到: 下载的Blob内容:“ PNG → 有这个怪异?在PNG之前和之后的箭头。

这是输出: enter image description here

所以我不确定自己做错了什么,我想我正确上传了(不确定我应该使用uploadLocalFile还是uploadLocalStream,但是我认为上传成功完成了),我在做什么下载错误但是,事实是我个人不会下载文件只是为了确保它能工作,而连接到数据库的其他程序将下载文件。 另外,如果您在a0008包含/./之后看到blob的链接,并且当我将该链接放置在浏览器中时,它会删除该部分,则我不知道该部分/./表示什么。

谢谢

1 个答案:

答案 0 :(得分:0)

blob URL由Azure Blob存储帐户的主机,容器名称和blob名称组成。例如,blob URL https://facerstorage.blob.core.windows.net/a00008/./sun.png包含容器名称a00008和blob名称./sun.png

根据您的代码,奇怪的Blob名称./sun.png由以下代码生成。

# In function uploadLocalFile
const fileName = path.basename(filePath);
const blockBlobURL = BlockBlobURL.fromContainerURL(containerURL, fileName);

# In function uploadStream
const fileName = path.basename(filePath).replace('.md', '-stream.md');
const blockBlobURL = BlockBlobURL.fromContainerURL(containerURL, fileName);

要修复此问题,只需检查上面的fileName变量的值即可确保它符合您的要求。

众所周知,您的代码来自官方文档Quickstart: Upload, download, list, and delete blobs using Azure Storage v10 SDK for JavaScript (preview),该文档通过npm i @azure/storage-blob使用了节点v10的Storage SDK的预览版。

还有用于节点v2的Storage SDK的另一个版本,可以通过npm install azure-storage安装,您可以参考GitHub存储库Azure/azure-storage-nodeREADME文档。

v2版本中,相关代码很简单。

var azure = require('azure-storage');
var accountName = '<your account name>';
var accountKey = '<your account key>';
var blobService = azure.createBlobService(accountName, accountKey);
var containerName = '<your container name>';
blobService.createContainerIfNotExists(containerName, {
  publicAccessLevel: 'blob'
}, function(error, result, response) {
  if (!error) {
    // if result = true, container was created.
    // if result = false, container already existed.
  }
});

var blobName = '<your blob name, such as sun.png>';
var localFile = '<your local file, such as ./sun.jpg>';
blobService.createBlockBlobFromLocalFile(containerName, blobName, localFile, function(error, result, response) {
  if (!error) {
    // file uploaded
  }
});

我看到您使用SDK v10发布了另一个SO线程Need help downloading image from Azure Blobs using NodeJS,但是我认为v2 SDK API现在对您来说很简单。