【发布时间】:2021-07-15 04:03:20
【问题描述】:
我正在尝试使用我的 react 应用程序使用 SAS 下载存储在 Azure Blob 存储中的文件,但遇到了问题。我有一个工作版本,它依赖于让烧瓶应用程序下载文件,然后将 blob 发送到反应应用程序以再次下载(显然不理想)。这是当前的实现:
烧瓶端点:
from azure.storage.blob import BlobServiceClient
blobService = BlobServiceClient(account_url="https://<account_name>.blob.core.windows.net/", credential=<blob_key>)
@app.route('/download')
def downloadFile():
filename = request.args.get('filename')
blob_client = blobService.get_blob_client(container='<container_name>', blob=filename)
blobObject = blob_client.download_blob()
fileObject = io.BytesIO(blobObject.readall())
return send_file(fileObject, attachment_filename=filename, as_attachment=True)
在反应中获取请求:
const getFile = (e) => {
e.preventDefault();
const filename = e.currentTarget.getAttribute('name');
axios({
url: `${serverUrl}/download?filename=${filename}`,
method: 'GET',
responseType: 'blob',
})
.then(({ data }) => {
const link = document.createElement('a');
const url = URL.createObjectURL(new Blob([data]));
link.href = url;
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch(() => {
_isMounted.current && setDisplayError(true);
});
};
我希望能够让我的 react 应用程序直接从 blob 存储下载文件,但我遇到了身份验证问题,以及单击下载按钮将浏览器导航到 url 而不仅仅是下载的另一个问题文件在该位置,同时停留在当前页面。这是有问题的新代码。
新的烧瓶端点:
from azure.storage.blob._shared_access_signature import BlobSharedAccessSignature
signatureService = BlobSharedAccessSignature('<account_name>', account_key='<azure_key>')
@app.route('/download')
def downloadFile():
filename = request.args.get('filename')
expiration = datetime.datetime.today() + datetime.timedelta(minutes=5)
container = '<container_name>'
key = signatureService.generate_blob(container, filename, permission='read', expiry=expiration)
data = {
'container': container,
'key': key
}
return app.response_class(
response=jsonifyWithNumPy(data),
status=200,
mimetype='application/json'
)
在反应中获取请求:
const getFile = (e) => {
e.preventDefault();
const filename = e.currentTarget.getAttribute('name');
axios
.get(`${serverUrl}/download?filename=${filename}`)
.then(({data}) => {
const url = `https://<account_name>.blob.core.windows.net/${data.container}/${filename}?${data.key}`
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch(() => {
_isMounted.current && setDisplayError(true);
});
};
这是我按照上述反应代码生成的 URL 时遇到的错误:
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:48c49456-001e-008b-263c-3625fd000000 Time:2021-04-20T23:23:26.1909093Z</Message>
<AuthenticationErrorDetail>Signature fields not well formed.</AuthenticationErrorDetail>
</Error>
【问题讨论】:
-
怎么样?你的问题解决了吗?如果我的帖子有帮助,请单击答案旁边的复选标记,将其从灰色切换为填写以接受它作为答案,它将帮助其他人并关闭此问题。我注意到您没有接受任何答案,如果您按时接受答案,其他人会更乐意帮助您。
标签: python reactjs flask azure-blob-storage