我一直在努力争取这一天。我正在直接测试Azure Blob存储上传并获得可怕的CORS问题。 "XMLHttpRequest cannot load https://tempodevelop.blob.core.windows.net/tmp/a4d8e867-f13e-343f-c6d3-a603…Ym0PlrBn%2BU/UzUs7QUhQw%3D&sv=2014-02-14&se=2016-10-12T17%3A59%3A26.638531. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 403."
我已经尝试过的事情:
整个代码可在此处找到:https://github.com/mikebz/azureupload
但相关部分在这里,前端上传:
<script>
/*
* not a true GUID, see here: http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
*/
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
function startUpload() {
var fileName = guid();
jQuery.getJSON("/formfileupload/signature/" + fileName , function(data) {
console.log("got a signature: " + data.bloburl);
uploadFile(data.bloburl, data.signature);
})
.fail(function(jqxhr, textStatus, error) {
console.log( "error: " + textStatus + " - " + error );
})
}
function uploadFile(bloburl, signature) {
var xhr = new XMLHttpRequest();
fileData = document.getElementById('fileToUpload').files[0];
xhr.open("PUT", bloburl + "?" + signature);
xhr.setRequestHeader('x-ms-blob-type', 'BlockBlob');
xhr.setRequestHeader('x-ms-blob-content-type', fileData.type);
result = xhr.send(fileData);
}
</script>
python中的签名生成代码在这里:
def generate_access_signature(self, filename):
"""
calls the Azure Web service to generate a temporary access signature.
"""
blob_service = BlobService(
account_name=self.account_name,
account_key=self.account_key
)
expire_at = datetime.utcnow()
expire_at = expire_at + timedelta(seconds = 30)
access_policy = AccessPolicy(permission="rwdl", expiry=expire_at.isoformat())
sas_token = blob_service.generate_shared_access_signature(
container_name="tmp",
blob_name = filename,
shared_access_policy=SharedAccessPolicy(access_policy)
)
return sas_token
答案 0 :(得分:5)
根据错误消息[响应具有HTTP状态代码403],可能是服务未启用CORS,或者没有CORS规则与预检请求匹配。细节请参考Cross-Origin Resource Sharing (CORS) Support for the Azure Storage Services。 或者可能是SAS签名不正确。 请尝试进行问题排查
您还可以使用Azure explore工具生成SAS令牌
答案 1 :(得分:1)
感谢Tom和Microsoft的支持,问题已得到解决 解决方案部分#1 - 确保使用Azure存储库for Python版本0.33或更高版本。
这是我的要求文件:
azure-common==1.1.4
azure-nspkg==1.0.0
azure-storage==0.33.0
cffi==1.8.3
cryptography==1.5.2
dj-database-url==0.4.1
Django==1.10.2
enum34==1.1.6
futures==3.0.5
gunicorn==19.6.0
idna==2.1
ipaddress==1.0.17
pep8==1.7.0
psycopg2==2.6.2
pyasn1==0.1.9
pycparser==2.16
python-dateutil==2.5.3
requests==2.11.1
six==1.10.0
whitenoise==3.2.2
第二个问题是生成签名。生成正确签名的代码在此处:
from azure.storage.blob import BlockBlobService, ContainerPermissions
from datetime import datetime, timedelta
class AzureUtils:
def __init__(self, account_name, account_key):
if account_name is None:
raise ValueError("account_name should not be None")
if account_key is None:
raise ValueError("account_key should not be None")
self.account_name = account_name
self.account_key = account_key
def generate_access_signature(self, filename):
"""
calls the Azure Web service to generate a temporary access signature.
"""
block_blob_service = BlockBlobService(
account_name=self.account_name,
account_key=self.account_key
)
expire_at = datetime.utcnow()
expire_at = expire_at + timedelta(seconds=30)
permissions = ContainerPermissions.READ | ContainerPermissions.WRITE | ContainerPermissions.DELETE | ContainerPermissions.LIST
sas_token = block_blob_service.generate_container_shared_access_signature(
"tmp",
permission=permissions,
expiry=expire_at
)
return sas_token
也可以在此处检索解决方案:https://github.com/mikebz/azureupload