在ASP.NET WebForms中,使用SAS URL上传Azure Blob时,由于内容安全策略(CSP)导致TypeError: Failed to fetch而失败
问题
我正使用来自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
问题
- 如何识别在IIS托管的ASP.NET应用中,哪一层覆盖了CSP头?
- CSP强制执行时,有没有推荐的通过SAS URL允许Azure Blob上传的方法?
- 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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。