You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JS上传文档至Azure Blob Storage时遇400认证格式错误

问题:拖拽PDF上传Azure Blob Storage时返回400认证错误

我编写了一段HTML/JS代码,实现将PDF文件拖拽上传至Azure Blob Storage并预览PDF的功能,但调用上传接口时返回400错误,提示:

Authentication information is not given in the correct format. Check the value of Authorization header.

已检查Blob存储容器及账户权限,仍未找到问题所在,代码如下:

<!DOCTYPE html>
<html>
<head>
    <title>File Upload to Azure Blob Storage</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js"></script>
</head>
<body>
    <div class="header">
        <span class="header-text">Document Request Analyzer</span>
    <div class="search-container">
        <input type="text" class="search-bar" placeholder="Search for specific request...">
    </div>
    </div>

    <div class="upload-container">
        <!--<div class="upload-icon">&#128193;</div>-->
        <div class="drop-area" id="dropArea">
            <span>Drag and Drop<br>Document<br>Request</span>
        </div>
            <button id="uploadButton" class="btn">Extract Request</button>
            <canvas id="pdfPreviewCanvas" class="preview-canvas"></canvas>
    </div>

    <script>
        const dropArea = document.getElementById('dropArea');
        const uploadButton = document.getElementById('uploadButton');
        const pdfPreviewCanvas = document.getElementById('pdfPreviewCanvas');
        const fileInput = document.createElement('input');

        fileInput.type = 'file';
        fileInput.accept = '.pdf';
        fileInput.style.display = 'none';
        document.body.appendChild(fileInput);

        dropArea.addEventListener('dragenter', (e) => {
            e.preventDefault();
            dropArea.classList.add('hover');
        });

        dropArea.addEventListener('dragover', (e) => {
            e.preventDefault();
        });

        dropArea.addEventListener('dragleave', () => {
            dropArea.classList.remove('hover');
        });

        dropArea.addEventListener('drop', (e) => {
            e.preventDefault();
            dropArea.classList.remove('hover');
            const file = e.dataTransfer.files[0];
            fileInput.files = e.dataTransfer.files;
            handleFileUpload(file);
        });

            uploadButton.addEventListener('click', () => {
            const file = fileInput.files[0];
            handleFileUpload(file);
        });


        async function handleFileUpload(file) {
            if (!file) {
                console.error('No file selected.');
                return;
            }

            const accountName = 'test';
            const containerName = 'test1234';
            const storageAccessKey = 'test';

            const currentDate = new Date();
            const expiryDate = new Date(currentDate);
            expiryDate.setMinutes(currentDate.getMinutes() + 5);
            const sasToken = 'testing';
            const blobName = file.name;
            const uploadUrl = `https://${accountName}.blob.core.windows.net/${containerName}/${blobName}${sasToken}`;

            const headers = new Headers();
            headers.append('x-ms-blob-type', 'GeneralPurposeV2');
            headers.append('x-ms-date', new Date().toUTCString());
            headers.append('Content-Length', 0);
            headers.append('x-ms-version', '2020-04-08');
            headers.append('Authorization', sasToken);

            // const formData = new FormData();
            // formData.append('file', file);

            const requestOptions = {
                method: 'PUT',
                headers: headers,
                body: file
            };

            try {
                const response = await fetch(uploadUrl, requestOptions);

                if (response.ok) {
                    console.log('File uploaded successfully');
                } else {
                    console.error('Error uploading file:', response.statusText);
                }
            } catch (error) {
                console.error('An error occurred:', error);
            }



            // Display uploaded PDF preview
            const pdfUrl = URL.createObjectURL(file);
            const loadingTask = pdfjsLib.getDocument(pdfUrl);

            try {
                const pdfDocument = await loadingTask.promise;
                const firstPage = await pdfDocument.getPage(1);

                const viewport = firstPage.getViewport({ scale: 1 });
                pdfPreviewCanvas.width = viewport.width;
                pdfPreviewCanvas.height = viewport.height;

                const canvasContext = pdfPreviewCanvas.getContext('2d');
                const renderContext = {
                    canvasContext,
                    viewport,
                };
                await firstPage.render(renderContext).promise;

                pdfPreviewCanvas.style.display = 'block';
            } catch (error) {
                console.error('Error rendering PDF:', error);
                pdfPreviewCanvas.style.display = 'none';
            }



        }
    </script>
</body>
</html>

错误原因及修复方案

1. SAS Token使用方式错误

你同时在uploadUrl拼接SAS Token,又在Authorization头中重复添加,这是错误的。Azure Blob Storage的SAS认证仅需将Token拼在URL末尾,无需额外设置Authorization头。

2. x-ms-blob-type值错误

x-ms-blob-type的有效值为BlockBlob、PageBlob或AppendBlob,你设置的GeneralPurposeV2是存储账户类型,并非Blob类型,会导致参数错误。

3. Content-Length设置错误

手动将Content-Length设为0,与实际上传的PDF文件大小不符,会触发请求异常。该值应由浏览器自动计算,无需手动设置。

4. 冗余的x-ms-date头

使用SAS Token认证时,无需手动设置x-ms-date,SAS Token本身已包含有效期信息。

修复后的核心代码片段

修改handleFileUpload函数中的相关部分:

async function handleFileUpload(file) {
    if (!file) {
        console.error('No file selected.');
        return;
    }

    const accountName = 'test';
    const containerName = 'test1234';
    // SAS Token需以?开头,示例:?sv=2020-04-08&ss=bfqt&srt=sco&sp=rwdlacupitfx&se=2024-05-20T00:00:00Z&st=2024-05-19T16:00:00Z&spr=https&sig=xxx
    const sasToken = '?sv=2020-04-08&...'; // 替换为你的有效SAS Token
    const blobName = file.name;
    const uploadUrl = `https://${accountName}.blob.core.windows.net/${containerName}/${blobName}${sasToken}`;

    const headers = new Headers();
    // 修正Blob类型为BlockBlob
    headers.append('x-ms-blob-type', 'BlockBlob');
    headers.append('x-ms-version', '2020-04-08');

    const requestOptions = {
        method: 'PUT',
        headers: headers,
        body: file
    };

    try {
        const response = await fetch(uploadUrl, requestOptions);

        if (response.ok) {
            console.log('File uploaded successfully');
        } else {
            const errorText = await response.text();
            console.error('Error uploading file:', response.statusText, errorText);
        }
    } catch (error) {
        console.error('An error occurred:', error);
    }

    // PDF预览部分保持不变...
}

额外注意事项

  • 确保SAS Token具备写入(w)权限,且有效期在当前时间范围内。
  • SAS Token必须以?开头,若生成时无此符号,需手动添加,否则URL解析会出错。
  • 禁止在前端代码中暴露存储账户访问密钥(storageAccessKey),存在安全风险,推荐使用SAS Token或后端签名上传请求。

内容的提问来源于stack exchange,提问作者Sani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 02:20:04