从 Javascript 调用 Azure 存储来提交分块上传时出现 CORS 错误

问题描述 投票:0回答:1

我希望用户将大文件直接上传到Azure存储中。我有一个 Flask Python Web 应用程序,但由于大小限制,我不希望将文件上传到我的 Web 服务器。

当用户选择要上传的文件并单击上传按钮时,会发生以下情况:

  1. 调用 API 来生成 SAS URL 和分配给要上传的文件的 Blob 名称。生成两者的代码是:
    blob_name = str(uuid.uuid4())  

    container_name = os.environ[default_container_name_setting]

    sas = generate_blob_sas(account_name=service.account_name,
                            account_key=access_key,
                            container_name=container_name,
                            blob_name=blob_name,
                            permission=BlobSasPermissions(write=True, read=True, create=True),
                            expiry=datetime.utcnow() + timedelta(hours=2)) 

    sas_url = 'https://' + service.account_name + '.blob.core.windows.net/' + container_name + '/' + blob_name + '?' + sas
    return sas_url, blob_name
  1. 然后通过 Javascript 分块上传文件:
const chunkSize = 1024 * 1024 * 20; 
const totalChunks = Math.ceil(file.size / chunkSize);
const blockIds = []; // Array to hold block IDs

for (let i = 0; i < totalChunks; i++) {
    const start = i * chunkSize;
    const end = Math.min(start + chunkSize, file.size);
    const chunk = file.slice(start, end);
    const blockId = btoa("block-" + i); // Base64 encode block ID
    blockIds.push(blockId);

    // Upload each chunk
    const uploadResponse = await fetch(sas_url + "&comp=block&blockid=" + blockId, {
        method: "PUT",
        headers: {
            "x-ms-blob-type": "BlockBlob",
            "Content-Type": file.type
        },
        body: chunk
    });

    if (!uploadResponse.ok) {
        return false;
    }
}

到目前为止它有效。然而,下一步是告诉 Azure 将这些块放在一起,仍然通过 Javascript:

const commitResponse = await fetch(sas_url + "&comp=commitBlockList", {
    method: "PUT",
    headers: {
        "Content-Type": "application/xml",
        "x-ms-version": "2020-10-02",
        "Content-Length": "0"
    },
    body: `<BlockList>${blockIds.map(id => `<Latest>${id}</Latest>`).join('')}</BlockList>`
});

if (!commitResponse.ok) {
    throw new Error("Failed to commit blocks to blob.");
}

此时我总是收到 CORS 错误:

访问“https://xxx.blob.core.windows.net/container/e07d13fa-bcd6-45cf-9eea-3295e17dc567?se=2024-11-01T04%2A18%3B30Q&sp=rcw&sv=2024-11-”来自原点“http://localhost:4449”的 04&sr=b&sig=CudrFGsJ1HGnYo6Bh3K7WVAabgdOAsPteWq47XKuKDI%3D&comp=commitBlockList' 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:无“Access-Control-Allow-Origin”标头存在于所请求的资源上。如果不透明响应满足您的需求,请将请求模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。

我知道我已经在 Azure 存储中正确设置了 CORS,因为上传部分可以正常工作。

在 Blob 服务选项卡下,我添加了 localhost 源,并使用允许的方法 GET、POST、OPTIONS 和 PUT。

我已尝试使用检索到的 Blob 名称重新生成另一个 SAS Url,但仍然收到 CORS 错误。

我错过了什么?

javascript python cors azure-blob-storage
1个回答
0
投票

我不认为这个问题与 CORS 有关,因为如果它与 CORS 相关,那么您在上传块时会收到错误(

PUT BLOCK
PUT BLOCK LIST
操作都是
Put
请求。

我相信问题出在您的块 ID 上。根据文档,块 ID 必须具有相同的长度。考虑到您正在添加块索引来获取块 id,在第 10 个块之后,您的块 id 长度将会不同。

尽量保持块id的长度相同。您可以使用 GUID 作为块 ID 或在计数器前添加一些零,以保持块 ID 的长度相同。

© www.soinside.com 2019 - 2024. All rights reserved.