Search code examples
javascriptangularjsng-file-upload

How to save images under a specific folder s3?


I am currently able to upload files under the root bucket in s3, however I would like to specify the folder to which it should save. Appending folder name to the url produces a 405.

Upload

$scope.s3upload = function(file) {
  Upload.upload({
    url: 'https://s3.amazonaws.com/XXX/',
    method: 'POST',
    data: {
      key: file.name,
      AWSAccessKeyId: "XXX",
      acl: 'public-read',
      policy: "XXX",
      signature: "XXX",
      "Content-Type": file.type != '' ? file.type : 'application/octet-stream',
      filename: file.name,
      polyfill IE8 - 9
      file: file
    }
  });
}

S3 CORS config

<?xml version="1.0" encoding="UTF-8"?>
    <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

S3 bucket policy

{
  "Version": "2008-10-17",
  "Id": "Policy1397632521960",
  "Statement": [{
    "Sid": "Stmt1397633323327",
    "Effect": "Allow",
    "Principal": {
      "AWS": "*"
    },
    "Action": [
      "s3:GetObject",
      "s3:PutObject"
    ],
    "Resource": "arn:aws:s3:::XXX/*"
  }]
}

Solution

  • You should specify the folder name as a prefix within the key, i.e.

      key: "folder/" + file.name,
      AWSAccessKeyId: "XXX",
      acl: 'public-read',
      policy: "XXX",
      signature: "XXX",
      "Content-Type": file.type != '' ? file.type : 'application/octet-stream',
      filename: file.name,
      polyfill IE8 - 9
      file: file
    

    Like in most Object Storage implementations, Amazon S3 folders are more of a concept than an actual resource type.