使用不带Azure SDK的REST API将流上传到Azure Blob存储 [英] Upload a Stream to Azure Blob Storage using REST API without Azure SDK

查看:64
本文介绍了使用不带Azure SDK的REST API将流上传到Azure Blob存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望以流的形式将文件上传到 Azure存储,但是我不想使用 Azure SDK ,而我想使用更多 REST API not BlobServiceClient 的通用方式.

有办法吗?相同的参考链接可以在这里找到:

问题通过Pamela的代码解决了+我发现的问题是初始化 .env 变量时出错.

解决方案

您可以使用放入Blob Rest API来上传流.有一个使用node.js的示例.

  const CryptoJS = require("crypto-js");const request = require("request");const fs = require('fs');const account ="account-name";const key ="account-key";var strTime = new Date().toUTCString();var filePath ='您的文件路径';const readStream = fs.createReadStream(filePath);var stat = fs.statSync(filePath);string_params = {'动词':'PUT','内容编码':'','Content-Language':'',内容长度":stat.size,'Content-MD5':'','Content-Type':'application/octet-stream','日期': '','If-Modified-Since':'','如果匹配':'','如果不匹配':'','If-Unmodified-Since':'','范围': '','CanonicalizedHeaders':'x-ms-blob-type:BlockBlob \ nx-ms-date:'+ strTime +'\ nx-ms-version:'+'2020-04-08 \ n','CanonicalizedResource':`/$ {account}/containername/myblob`}var strToSign =`$ {string_params ['verb']} \ n $ {string_params ['Content-Encoding']} \ n $ {string_params ['Content-Language']} \ n $ {string_params ['Content-Length']} \ n $ {string_params ['Content-MD5']} \ n $ {string_params ['Content-Type']} \ n $ {string_params ['Date']} \ n $ {string_params ['If-Modified-因为']} \ n $ {string_params ['If-Match']} \ n $ {string_params ['If-None-Match']} \ n $ {string_params ['If-Unmodified-Since']} \ n ${string_params ['Range']} \ n $ {string_params ['CanonicalizedHeaders']} $ {string_params ['CanonicalizedResource']}``console.log(strToSign);var secret = CryptoJS.enc.Base64.parse(key);var hash = CryptoJS.HmacSHA256(strToSign,secret);var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);var auth =`SharedKey $ {account}:`+ hashInBase64;console.log(auth)const options = {网址:`https://$ {account} .blob.core.windows.net/containername/myblob`,标头:{授权:auth,'x-ms-blob-type':'BlockBlob',"x-ms-date":strTime,"x-ms-version":"2020-04-08","Content-Type":"application/octet-stream",内容长度":stat.size},正文:readStream};函数回调(错误,响应,正文){console.log(response.statusCode);console.log(response.statusMessage);if(!error&& response.statusCode == 200){console.log(错误);console.log(response);console.log(body);}}request.put(options,callback); 

I wish to upload files in the form of a stream into Azure Storage but I don't want to use Azure SDK instead I want to do it in a more generic way using REST API and not BlobServiceClient.

Is there a way to do so? The reference links for the same can be found here:

https://docs.microsoft.com/en-us/azure/storage/common/storage-samples-javascript?toc=/azure/storage/blobs/toc.json#blob-samples

https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/storage/storage-blob/samples/javascript/advanced.js#L74

But the links mentioned here propose a solution using Azure SDK. I want to do it without Azure SDK

Here's the code:

const CryptoJS = require("crypto-js");
const request = require("request");
const fs = require("fs");

const account = process.env.ACCOUNT_NAME || "";
const key = process.env.ACCOUNT_KEY || "";
const containerName = "demo";
const blobName = "dummyfile.txt";
var strTime = new Date().toUTCString();

// read file to Stream
var filePath = `${__dirname}/README.md`;
const readStream = fs.createReadStream(filePath);
var stat = fs.statSync(filePath);

string_params = {
  verb: "PUT",
  "Content-Encoding": "",
  "Content-Language": "",
  "Content-Length": stat.size,
  "Content-MD5": "",
  "Content-Type": "application/octet-stream",
  Date: "",
  "If-Modified-Since": "",
  "If-Match": "",
  "If-None-Match": "",
  "If-Unmodified-Since": "",
  Range: "",
  CanonicalizedHeaders:
    "x-ms-blob-type:BlockBlob\nx-ms-date:" +
    strTime +
    "\nx-ms-version:" +
    "2020-04-08\n",
  CanonicalizedResource: `/${account}/${containerName}/${blobName}`,
};

var strToSign = `${string_params["verb"]}\n${string_params["Content-Encoding"]}\n${string_params["Content-Language"]}\n${string_params["Content-Length"]}\n${string_params["Content-MD5"]}\n${string_params["Content-Type"]}\n${string_params["Date"]}\n${string_params["If-Modified-Since"]}\n${string_params["If-Match"]}\n${string_params["If-None-Match"]}\n${string_params["If-Unmodified-Since"]}\n${string_params["Range"]}\n${string_params["CanonicalizedHeaders"]}${string_params["CanonicalizedResource"]}`;

var secret = CryptoJS.enc.Base64.parse(key);
var hash = CryptoJS.HmacSHA256(strToSign, secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var auth = `SharedKey ${account}:` + hashInBase64;

const options = {
  url: `https://${account}.blob.core.windows.net/${containerName}/${blobName}`,
  headers: {
    Authorization: auth,
    "x-ms-blob-type": "BlockBlob",
    "x-ms-date": strTime,
    "x-ms-version": "2020-04-08",
    "Content-Type": "application/octet-stream",
    "Content-Length": stat.size,
  },
  body: readStream,
};

function callback(error, response, body) {
  console.log(response.statusCode);
  console.log(response.statusMessage);
  if (!error && response.statusCode == 200) {
    console.log(error);
    console.log(response);
    console.log(body);
  }
}

request.put(options, callback);

The error which I am getting is:

TypeError: Cannot read property 'statusCode' of undefined

Edit: The problem was solved by Pamela's code + the issue I found was there's was an error in initializing .env variables.

解决方案

You could use Put Blob Rest API to upload a stream. There is a sample using node.js.

const CryptoJS = require("crypto-js");
const request = require("request");
const fs = require('fs');

const account = "account-name";
const key = "account-key";
var strTime = new Date().toUTCString();

var filePath = 'your-file-path';
const readStream = fs.createReadStream(filePath);
var stat = fs.statSync(filePath);

string_params = {
    'verb': 'PUT',
    'Content-Encoding': '',
    'Content-Language': '',
    'Content-Length': stat.size,
    'Content-MD5': '',
    'Content-Type': 'application/octet-stream',
    'Date': '',
    'If-Modified-Since': '',
    'If-Match': '',
    'If-None-Match': '',
    'If-Unmodified-Since': '',
    'Range': '',
    'CanonicalizedHeaders': 'x-ms-blob-type:BlockBlob\nx-ms-date:' + strTime + '\nx-ms-version:' + '2020-04-08\n',
    'CanonicalizedResource': `/${account}/containername/myblob`
}


var strToSign = `${string_params['verb']}\n${string_params['Content-Encoding']}\n${string_params['Content-Language']}\n${string_params['Content-Length']}\n${string_params['Content-MD5']}\n${string_params['Content-Type']}\n${string_params['Date']}\n${string_params['If-Modified-Since']}\n${string_params['If-Match']}\n${string_params['If-None-Match']}\n${string_params['If-Unmodified-Since']}\n${string_params['Range']}\n${string_params['CanonicalizedHeaders']}${string_params['CanonicalizedResource']}`
console.log(strToSign);

var secret = CryptoJS.enc.Base64.parse(key);
var hash = CryptoJS.HmacSHA256(strToSign, secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var auth = `SharedKey ${account}:` + hashInBase64;
console.log(auth)

const options = {
    url: `https://${account}.blob.core.windows.net/containername/myblob`,
    headers: {
        Authorization: auth,
        'x-ms-blob-type': 'BlockBlob',
        "x-ms-date": strTime,
        "x-ms-version": "2020-04-08",
        'Content-Type': "application/octet-stream",
        'Content-Length': stat.size
    },
    body: readStream
};

function callback(error, response, body) {
    console.log(response.statusCode);
    console.log(response.statusMessage);
    if (!error && response.statusCode == 200) {
        console.log(error);
        console.log(response);
        console.log(body);
    }
}

request.put(options, callback);

这篇关于使用不带Azure SDK的REST API将流上传到Azure Blob存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆