在ASP.NET WebForms中,使用SAS URL上传Azure Blob时,由于内容安全策略(CSP)导致TypeError: Failed to fetch而失败

前端开发 2026-07-12

问题

我正使用来自ASP.NET WebForms后端生成的SAS URL,将浏览器中的文件直接上传到Azure Blob存储。上传在逻辑上可以工作,但浏览器总是抛出:

TypeError: Failed to fetch
Refused to connect because it violates the document's Content Security Policy

控制台错误:

Connecting to 'https://<storage-account>.blob.core.windows.net/...'
violates the following Content Security Policy directive:
"default-src 'self' https://apps.itl.co.tz/broker/".
Note that 'connect-src' was not explicitly set.

环境

  • ASP.NET WebForms (.NET Framework)
  • JavaScript fetch() API
  • Azure Blob存储(BlockBlob)
  • SAS令牌上传
  • IIS托管应用
  • 浏览器:Chrome / Edge

后端(SAS生成)

<System.Web.Services.WebMethod()>
<ScriptMethod(ResponseFormat:=ResponseFormat.Json)>
Public Shared Function GetUploadSasUrl(fileName As String) As String

    Dim connectionString As String =
        clsCommon.GetConfigurationValue("STORAGE_CONN_STRING")

    Dim containerName As String =
        clsCommon.GetConfigurationValue("STORAGE_CONTAINER")

    Dim storageAccount = CloudStorageAccount.Parse(connectionString)
    Dim blobClient = storageAccount.CreateCloudBlobClient()
    Dim container = blobClient.GetContainerReference(containerName)

    Dim blobName = Uri.EscapeDataString(fileName)
    Dim blockBlob = container.GetBlockBlobReference(blobName)

    Dim sasPolicy As New SharedAccessBlobPolicy() With {
        .SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(10),
        .Permissions = SharedAccessBlobPermissions.Write
    }

    Dim sasToken = blockBlob.GetSharedAccessSignature(sasPolicy)

    Return blockBlob.Uri.ToString() & sasToken
End Function

返回的URL示例:

https://dbatchattachmentsuat.blob.core.windows.net/dbatch-uat/test12.jpg?sv=...&sp=w

前端上传代码

async function uploadToAzure(file, sasUrl) {

    try {

        const response = await fetch(sasUrl, {
            method: "PUT",
            headers: {
                "x-ms-blob-type": "BlockBlob",
                "Content-Type": file.type
            },
            body: file
        });

        console.log("STATUS:", response.status);

    } catch (err) {
        console.error("FETCH ERROR:", err);
    }
}

Azure配置

Blob服务 → CORS:

  • 允许的来源:https://localhost:44380
  • 允许的方法:PUT, GET, OPTIONS
  • 允许的头:*
  • 暴露的头:*

CSP配置尝试

web.config 中添加:

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Content-Security-Policy"
           value="default-src 'self' https://apps.itl.co.tz/broker/;
                  connect-src 'self' https://dbatchattachmentsuat.blob.core.windows.net;" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

然而,浏览器仍然报告:

connect-src not explicitly set
default-src is used as fallback

这表明可能有另一个CSP头覆盖了它。


观察到的行为

  • SAS URL有效
  • 已配置Azure CORS
  • 请求从未到达Azure
  • 浏览器在网络调用发出之前就阻止了请求
  • fetch() 立即抛出 TypeError: Failed to fetch

问题

  1. 如何识别在IIS托管的ASP.NET应用中,哪一层覆盖了CSP头?
  2. CSP强制执行时,有没有推荐的通过SAS URL允许Azure Blob上传的方法?
  3. Azure Blob PUT 上传所需的正确CSP配置是什么?

如能就诊断CSP覆盖或最佳实践配置提供指导,将不胜感激。

解决方案

好吧,我们先聚焦你的HTTP Web服务器配置:

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Content-Security-Policy"
           value="default-src 'self' https://apps.itl.co.tz/broker/;
                  connect-src 'self' https://dbatchattachmentsuat.blob.core.windows.net;" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

在此处的值不要使用空格。你有一个分号,然后是制表符或空格分隔connect-src。在XML中这可能会将非预期的值传递给客户端浏览器。请使用单行,如下所示(default-src也不要在其中使用路径或尾部斜杠:

<add name="Content-Security-Policy"
           value="default-src 'self' https://apps.itl.co.tz; connect-src 'self' https://dbatchattachmentsuat.blob.core.windows.net;" />

另外,鉴于你的CORS策略使用localhost,我也假设你是在本地部署的应用进行测试。请记住,如果该应用在https://localhost:44380之外的任何地方运行,CORS将阻止请求,因此若是这种情况,你需要将用户正在浏览的来源添加进来。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章