簡體   English   中英

Upload a Stream to Azure Blob Storage using REST API without Azure SDK

[英]Upload a Stream to Azure Blob Storage using REST API without Azure SDK

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 .

有沒有辦法這樣做? 可以在此處找到相同的參考鏈接:

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

但是這里提到的鏈接提出了一個使用Azure SDK的解決方案。 我想做沒有Azure SDK

這是代碼:

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);

我得到的錯誤是:

TypeError: Cannot read property 'statusCode' of undefined

錯誤截圖

編輯:Pamela 的代碼解決了這個問題 + 我發現的問題是初始化.env變量時出錯。

您可以嘗試使用 Azure REST API 進行 Blob 操作。 您可以在此處找到 Blob 的 REST API - Operations on Blob

問題是您將如何在運行時處理 stream 上傳。 Azure SDK 支持 stream 上傳。 但是,對於 REST API,您需要自己處理。

上傳 stream 或並行數據,您需要圍繞此 REST API 調用來實現這一點

希望您覺得這個有幫助。

您可以使用Put Blob Rest API 上傳 stream。 有一個使用 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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM