我尝试使用Java客户端在Azure上设置CORS属性。执行代码后,我运行HTML5代码上传文件并在chrome javascript控制台中面临以下错误:
最大块大小= 47276
总积数= 1
的https:myacc.blob.core.windows.net/mycon/ch1.jpg SR = C&安培; SV = 2015年4月5日&安培; SIG = djbVxIBlyVy18bV0SkqNSLql1n9efAVcYnGy3VsGKis%3D&安培; SI =冠军
当前文件指针= 0字节读取= 47276
阻止id = block-000000
的https:myacc.blob.core.windows.net/mycon/ch1.jpg SR = C&安培; SV = 2015-0 ... kqNSLql1n9efAVcYnGy3VsGKis%3D&安培; SI =冠军&安培;可比=块&安培;块标识= YmxvY2stMDAwMDAw
无法加载资源:服务器响应状态为403(未启用CORS或未找到此请求的匹配规则。)
XMLHttpRequest无法加载 HTTPS:?myacc.blob.core.windows.net/mycon/ch1.jpg SR = C&安培; SV = 2015-0 ... kqNSLql1n9efAVcYnGy3VsGKis%3D&安培; SI =健康&安培;可比=块&安培;块标识= YmxvY2stMDAwMDAw
对预检请求的响应未通过访问控制检查:否' Access-Control-Allow-Origin'标题出现在请求的上 资源。 Origin' file://'因此不允许访问。该 响应有HTTP状态码403。
我想知道为什么在Java客户端成功执行后它没有设置CORS?另外,我如何验证规则政策" champ"如果我生成的SAS正确并且创建了CORS属性
,则配置正确这是Java客户端代码:
public class CORS_and_SAS {
public static void main(String[] args) {
// Define the connection-string with your values
final String storageConnectionString ="DefaultEndpointsProtocol=http;" + "AccountName=myacc;" + "AccountKey=B2q4AGp6YoRsTREXIkOv3e/Sxf46YzqzfnM9F8U+o7VA5Y3EiKc+CuritnvuyZxGXKNOQ5nJy2KfkniF970on1dQ==";
try {
// Retrieve storage account from connection-string.
CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);
// Create the blob client.
CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
// Get a reference to a container.
// The container name must be lower case
CloudBlobContainer container = blobClient.getContainerReference("mycon");
// Create the container if it does not exist.
//container.createIfNotExists();
// Set CORS support
//ServiceProperties blobServiceProperties = blobClient.GetServiceProperties();
ServiceProperties propers = getCORS();
blobClient.uploadServiceProperties(propers);
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
GregorianCalendar calendar =
new GregorianCalendar(TimeZone.getTimeZone("UTC"));
calendar.setTime(new Date());
policy.setSharedAccessStartTime(calendar.getTime()); //Immediately applicable
calendar.add(Calendar.HOUR, 3000); //Applicable time-span is 3000 hours
policy.setSharedAccessExpiryTime(calendar.getTime());
policy.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ,
SharedAccessBlobPermissions.WRITE, SharedAccessBlobPermissions.DELETE,
SharedAccessBlobPermissions.LIST));
BlobContainerPermissions containerPermissions = new BlobContainerPermissions();
//Private container with no access for anonymous users
containerPermissions.setPublicAccess(BlobContainerPublicAccessType.OFF);
//Name the shared access policy: heath
containerPermissions.getSharedAccessPolicies().put("champ", policy);
container.uploadPermissions(containerPermissions);
//Generate the policy SAS string for heath access
String sas = container.generateSharedAccessSignature(
new SharedAccessBlobPolicy(),"champ");
System.out.println("The stored access policy signature:");
System.out.println(sas);
} catch (Exception e) {
// Output the stack trace.
e.printStackTrace();
}
}
private static ServiceProperties getCORS() {
// TODO Auto-generated method stub
ServiceProperties propers = new ServiceProperties();
CorsProperties corsprop = propers.getCors();
CorsRule cr = new CorsRule();
List<String> allowedHeaders = new ArrayList<String>();
allowedHeaders.add("x-ms-*");
List<String> exposedHeaders = new ArrayList<String>();
exposedHeaders.add("x-ms-*");
cr.setAllowedHeaders(allowedHeaders);
cr.setExposedHeaders(exposedHeaders);
EnumSet<CorsHttpMethods> allowedMethod = EnumSet.of(CorsHttpMethods.PUT,CorsHttpMethods.GET,CorsHttpMethods.POST,CorsHttpMethods.HEAD,CorsHttpMethods.DELETE);
//EnumSet<CorsHttpMethods> allowedMethod1 = EnumSet.of(CorsHttpMethods.GET);
cr.setAllowedMethods(allowedMethod);
List<String> allowedOrigin = new ArrayList<String>();
allowedOrigin.add("*");
cr.setAllowedOrigins(allowedOrigin);
cr.setMaxAgeInSeconds(600);
corsprop.getCorsRules().add(cr);
//corsprop.getCorsRules().add(cr);
propers.setCors(corsprop);
return propers;
}
}
答案 0 :(得分:0)
我尝试重现该问题,并仔细检查了Java客户端代码&amp; JS控制台中的错误。我发现问题是由上传文件URL使用blob容器共享访问签名引起的。
以下是您修改的Java代码。
private static final String accountName = "<account-name>";
private static final String accountKey = "<account-key>";
private static final String connectionStringTemplate = "DefaultEndpointsProtocol=http;AccountName=%s;AccountKey=%s";
private static final String containerName = "<block-blob-container-name>";
private static final String blobFileName = "<blob-file-name>";
public static void main(String[] args) throws InvalidKeyException, URISyntaxException, StorageException {
String connectionString = String.format(connectionStringTemplate, accountName, accountKey);
CloudStorageAccount account = CloudStorageAccount.parse(connectionString);
CloudBlobClient blobClient = account.createCloudBlobClient();
/*
* Enable CORS
*/
// CORS should be enabled once at service startup
// Given a BlobClient, download the current Service Properties
ServiceProperties blobServiceProperties = blobClient.downloadServiceProperties();
// Enable and Configure CORS
CorsProperties cors = new CorsProperties();
CorsRule corsRule = new CorsRule();
List<String> allowedHeaders = new ArrayList<String>();
allowedHeaders.add("*");
EnumSet<CorsHttpMethods> allowedMethods = EnumSet.of(CorsHttpMethods.PUT, CorsHttpMethods.GET, CorsHttpMethods.HEAD, CorsHttpMethods.POST);
System.out.println(Arrays.toString(allowedMethods.toArray()));
List<String> allowedOrigins = new ArrayList<String>();
allowedOrigins.add("*");
List<String> exposedHeaders = new ArrayList<String>();
exposedHeaders.add("*");
int maxAgeInSeconds = 1800;
corsRule.setAllowedHeaders(allowedHeaders);
corsRule.setAllowedMethods(allowedMethods);
corsRule.setAllowedOrigins(allowedOrigins);
corsRule.setExposedHeaders(exposedHeaders);
corsRule.setMaxAgeInSeconds(maxAgeInSeconds);
cors.getCorsRules().add(corsRule);
blobServiceProperties.setCors(cors);
// Commit the CORS changes into the Service Properties
blobClient.uploadServiceProperties(blobServiceProperties);
/*
* Generate the SAS for the uploading url
*/
CloudBlobContainer container = blobClient.getContainerReference(containerName);
CloudBlockBlob blockBlob = container.getBlockBlobReference(blobFileName);
SharedAccessBlobPolicy sharedAccessBlobPolicy = new SharedAccessBlobPolicy();
GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
calendar.setTime(new Date());
sharedAccessBlobPolicy.setSharedAccessStartTime(calendar.getTime());
calendar.add(Calendar.HOUR, 1);
sharedAccessBlobPolicy.setSharedAccessExpiryTime(calendar.getTime());
sharedAccessBlobPolicy.setPermissions(EnumSet.of(SharedAccessBlobPermissions.WRITE));
String sas = blockBlob.generateSharedAccessSignature(sharedAccessBlobPolicy, null);
System.out.println(sas);
String blobUploadSASURL = String.format("https://%s.blob.core.windows.net/%s/%s?%s", accountName, containerName, blobFileName, sas);
System.out.println(blobUploadSASURL);
}
运行代码并获取上传blob SAS Url作为表单https://<account-name>.blob.core.windows.net/<container>/<blob-file-name>?sig=<SIG>&st=2015-12-01T11%3A51%3A20Z&se=2015-12-01T12%3A51%3A20Z&sv=2015-04-05&sp=r&sr=b
使用带标头x-ms-blob-type: BlockBlob
的PUT方法成功上传文件。
有关执行此操作的更多详细信息和示例ajax代码,请参阅Azure存储团队http://blogs.msdn.com/b/windowsazurestorage/archive/2014/02/03/windows-azure-storage-introducing-cors.aspx中的博客。