为 Azure Blob 存储启用 CORS

Posted

技术标签:

【中文标题】为 Azure Blob 存储启用 CORS【英文标题】:Enable CORS for azure blob storage 【发布时间】:2016-07-24 13:26:26 【问题描述】:

我对@9​​87654329@ 完全陌生,并且在为角度客户端设置CORS 时遇到问题。我正在使用这个module。我在nodejs 服务器上成功生成了sasToken

我还检查了这些参考资料:Set Blob Service Properties、Cross-Origin Resource Sharing (CORS) Support for the Azure Storage Services 和 Windows Azure Storage: Introducing CORS,但我真的觉得在哪里做/放置这些代码令人困惑。

到目前为止,我所做的是:

在 AGULAR 控制器中:

// this is the service that generate the sasToken from the server
getService.getSasToken(filename)
        .then(function (response) 
            // response = 
            //    sasToken : "asa7sya....",
            //    token: "the shared key",
            //    account: "the storage account name"
            // 

            function createCORSRequest(method, url) 
                var xhr = new XMLHttpRequest();
                if ("withCredentials" in xhr) 
                    xhr.open(method, url, true);
                    xhr.setRequestHeader("Content-Type","application/xml");
                    xhr.setRequestHeader("x-ms-version", "2013-08-15");
                    xhr.setRequestHeader("Authorization", response.token);
                    xhr.setRequestHeader("myaccount", response.account);
                 else if (typeof XDomainRequest != "undefined") 
                    xhr = new XDomainRequest();
                    xhr.open(method, url, true);
                    xhr.setRequestHeader("Content-Type","application/xml");
                    xhr.setRequestHeader("x-ms-version", "2013-08-15");
                    xhr.setRequestHeader("Authorization", response.token);
                    xhr.setRequestHeader("myaccount", response.account);
                 else 
                    xhr = null;
                
                return xhr;
            

            var xhr = createCORSRequest('PUT', 'https://foo.blob.core.windows.net?restype=service&comp=properties');
            if (!xhr) 
                throw new Error('CORS not supported');
            else
                // Response handlers.
                xhr.onload = function() 
                    alert('Response from CORS request to ' + xhr.responseText);
                    azureBlob.upload(
                        baseUrl: "https://foo.blob.core.windows.net/bar/"+filename,
                        sasToken: "?"+response.sasToken,
                        file: blobFile,
                        progress: function (progress) 
                            console.log("progress", progress);
                        ,
                        complete: function (complete) 
                            console.log("complete", complete);
                        ,
                        error: function (error) 
                            console.log("error", error);
                        ,
                        // blockSize: // What do I put here?
                    )
                ;

                xhr.onerror = function() 
                    alert('Woops, there was an error making the request.');
                ;
                $.ajax(
                    type: "GET",
                    url: "../scripts/cors.xml", // local xml file 
                    dataType: "xml",
                    success: function(xml)
                        console.log("xml", xml);
                        xhr.send(xml);
                    
                );

            
        ,function (error) 
            console.log(error);
        )

CORS.XML

    <?xml version="1.0" encoding="utf-8"?>
<StorageServiceProperties>
    <Logging>
        <Version>1.0</Version>
        <Delete>true</Delete>
        <Read>false</Read>
        <Write>true</Write>
        <RetentionPolicy>
            <Enabled>true</Enabled>
            <Days>7</Days>
        </RetentionPolicy>
    </Logging>
    <HourMetrics>
        <Version>1.0</Version>
        <Enabled>true</Enabled>
        <IncludeAPIs>false</IncludeAPIs>
        <RetentionPolicy>
            <Enabled>true</Enabled>
            <Days>7</Days>
        </RetentionPolicy>
    </HourMetrics>
    <MinuteMetrics>
        <Version>1.0</Version>
        <Enabled>true</Enabled>
        <IncludeAPIs>true</IncludeAPIs>
        <RetentionPolicy>
            <Enabled>true</Enabled>
            <Days>7</Days>
        </RetentionPolicy>
    </MinuteMetrics>
    <Cors>
        <CorsRule>
            <AllowedOrigins>*</AllowedOrigins>
            <AllowedMethods>GET,PUT,POST</AllowedMethods>
            <MaxAgeInSeconds>500</MaxAgeInSeconds>
            <ExposedHeaders>x-ms-meta-data*,x-ms-meta-customheader</ExposedHeaders>
            <AllowedHeaders>x-ms-meta-target*,x-ms-meta-customheader</AllowedHeaders>
        </CorsRule>
    </Cors>
    <DefaultServiceVersion>2013-08-15</DefaultServiceVersion>
</StorageServiceProperties>

上面的代码是基于这个GUIDE

但是我仍然收到此错误:

以前有人做过吗?请分享您的代码。

提前致谢。

【问题讨论】:

仅供参考,CORS 强制在所有跨源请求之前发出飞行前 HTTP OPTIONS 请求,因此您还需要将 OPTIONS 设置为允许的方法&lt;AllowedMethods&gt;GET,PUT,POST,OPTIONS&lt;/AllowedMethods&gt; 有MDN article about CORS 中有关飞行前 OPTIONS 请求的部分。 @ChristoferEliasson 我添加了 OPTIONS,还是一样。 【参考方案1】:

我可以看到您对预检请求的响应不包含显示您的预检请求失败的“Access-Control-Allow-origin”标头。这意味着您没有获得服务器端的许可。

您说您的代码基于Guide。但是指南说 Date 或 x-ms-date 是必需的 请求标头未出现在您的请求标头中,导致您的预检请求被拒绝。

我的建议是将 x-ms-date 添加到您的请求标头中,然后重试。 您可以查看this article 以获取有关“预检请求”和“实际请求”的详细信息。

【讨论】:

嗨,亚历克斯感谢您的回复,我想通了并进行了更改,稍后我会更新我的问题。 :)【参考方案2】:

今天早上我也遇到了同样的问题。做了一些研究,发现不需要更改代码库。

所需的更改是在 Azure 容器级别。如下图:

输入通配符或特定通配符,这将使事情正常进行。

【讨论】:

【参考方案3】:

我花了两天时间。我必须在 blob 存储 cors 设置中对原点进行硬编码。 * 不起作用。将您的客户网址放在 cors 选项中,而不是 *,我敢打赌事情会更好。 &lt;AllowedOrigins&gt;*&lt;/AllowedOrigins&gt; 在开发时更改为您的本地主机。

还将HEAD 添加到所需的方法中

【讨论】:

以上是关于为 Azure Blob 存储启用 CORS的主要内容,如果未能解决你的问题,请参考以下文章

创建 Azure 存储 Blob 容器时出现错误 403(已启用存储防火墙

Azure 存储。得到 403 [url](未启用 CORS 或未找到此请求的匹配规则。)

如何为 Azure 上的 Node.js Api 应用启用 BLOB 日志记录?

在 Azure 移动服务中启用 CORS - OPTIONS 未授权

在 Azure 上为 .NET Web Api 启用 CORS

Azure Vnet Blob 存储