简体   繁体   中英

How to upload image to aws s3 using react and django rest framework

I am trying to upload image to aws s3 using react and drf. I am following this heroku documentation . I am getting error mentioning Request failed with status code 400.

as they have suggested in the link first I created signed url from backend.

urlpatterns = [ 
   path('api/create-permission/aws-s3/', SignS3Upload.as_view(), name='aws-s3'),    
]

import os
import boto3
import mimetypes
s3 = boto3.client('s3')

class SignS3Upload(APIView):
    # authentication_classes = (authentication.SessionAuthentication,)
    # permission_classes = [IsAuthenticated, ]

    def get(self, request):
        s3_bucket = os.environ.get('AWS_STORAGE_BUCKET_NAME')
        file_name = request.GET['image_name']
        file_type = mimetypes.guess_type(file_name)[0]
        presigned_post = s3.generate_presigned_post(
            Bucket=s3_bucket,
            Key=file_name,
            Fields={"acl": "public-read", "Content-Type": file_type},
            Conditions=[
                {"acl": "public-read"},
                {"Content-Type": file_type}
            ],
            ExpiresIn=3600
        )

        data = {
            "signed_url": presigned_post,
            'url': 'https://%s.s3.amazonaws.com/%s' % (s3_bucket, file_name)
        }
        return Response(data) 

In frontend I am using React and Redux. here how I am sending request from frontend

export const getSignedRequest = (image) => (dispatch, getState) => {

    const image_name = image.name

    axios.get('https://my-site.herokuapp.com/api/blog/api/create-permission/aws-s3/', { params: { image_name } })
        .then((res) => {
            dispatch({
                type: GET_PARTICULAR_BLOG_IMG_UPLOAD,
                payload: res.data
            });


            var postData = new FormData();
            for (key in res.data.fields) {
                postData.append(key, res.data.fields[key]);
            }
            postData.append('file', image_name);

            return axios.post(res.data.url, postData);
        })
        .then((res) => {
            dispatch({
                type: GET_PARTICULAR_BLOG_IMG_UPLOAD_AWS,
                payload: res.data
            });
        })
        .catch((err) => {
            console.log(err)
        });

};

I received the response from first axios request in frontend like below

signed_url: {
  url: 'https://my-site.s3.amazonaws.com/',
  fields: {
    acl: 'public-read',
    'Content-Type': 'image/jpeg',
    key: 'xxxxxxxxxxx.jpg',
    AWSAccessKeyId: 'xxx_access_id_xxxx',
    policy: 'xxx_policy_xxx',
    signature: 'xxx_signature_xxx'
  }
},
url: 'https://my-site.s3.amazonaws.com/xxxxxxxxxxx.jpg'

},

here is settings.py

AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

you can use the below library for the uploading image that will

https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM