当前位置: 首页 > 知识库问答 >
问题:

如何使用带有react.js的预签名Url将文件上传到S3

景英杰
2023-03-14
class S3Controller:
    def __init__(self, client=None, bucket=None):
        self.client = client
        self.bucket = bucket

    def signed_url(self, filename):
        filename = filename.replace('/', '-').replace(' ', '-')
        date = datetime.now()
        key = f"audio/{date.year}/{date.month}/{date.day}/{filename}"
        url = self.client.generate_presigned_url(
            ClientMethod='put_object',
            ExpiresIn=3600,
            Params={
                'Bucket': self.bucket,
                'Key': key,
            }
        )
        return url
import React, { Component, Fragment } from 'react';
import { withRouter } from 'react-router-dom';
import { S3SignedUrl } from '../query';
import { withApollo } from 'react-apollo';
import AudioUploadButton from '../components/AudioUploadButton';
import axios from 'axios';


class UpdateAudio extends Component {
    constructor(props) {
        super(props);
        this.site = "5d517862-0630-431c-94b1-bf34de6bfd8b"
        this.state = {
            audioSelected: {},
            audioLoaded: 0
        }
        this.onSelect = this.onSelect.bind(this);
        this.onUpload = this.onUpload.bind(this);
    }

    onSelect = (event) => {
        const fileInfo = event.target.files[0];
        this.setState({audioSelected: fileInfo});
    }

    onUpload = async () => {
        let resp = await this.props.client.query({ query: S3SignedUrl, variables: {filename: this.state.audioSelected.name}});

        let { data } = resp;
        let endpoint = data.s3SignedUrl.url;

        axios.put(endpoint, this.state.audioSelected, {
            onUploadProgress: ProgressEvent => {
                this.setState({
                    audioLoaded: (ProgressEvent.loaded / ProgressEvent.total*100)
                })
            }
        })
        .then(res => {
            console.log(res);
        })

    }

    render() {
        return (
            <Fragment>
                <AudioUploadButton onSelect={this.onSelect} onUpload={this.onUpload} audioSelected={this.state.audioSelected} audioLoaded={this.state.audioLoaded} />
            </Fragment>
        )
    }
}

UpdateAudio = withRouter(UpdateAudio)

export default withApollo(UpdateAudio);
import React from 'react';
import { Grid, Button, Typography, Fab } from '@material-ui/core';
import { withStyles } from '@material-ui/core/styles';
import CloudUploadIcon  from '@material-ui/icons/CloudUpload';


const styles = theme => ({
button: {
    margin: theme.spacing.unit,
},
input: {
    display: 'none',
},
fab: {
    margin: theme.spacing.unit,
},
});


class AudioUploadButton extends React.Component {
    render() {
        let { classes } = this.props;
        let { name, size } = this.props.audioSelected;
        let loaded = this.props.audioLoaded;

        return (
            <Grid container spacing={8} >
                <Grid item md={2} xs={12}>
                    <input
                        accept="audio/*"
                        className={classes.input}
                        id="contained-button-file"
                        type="file"
                        onChange = {this.props.onSelect}
                    />
                    <label htmlFor="contained-button-file">
                        <Button variant="contained" component="span" className={classes.button}>Select</Button>
                    </label>
                </Grid>
                <Grid item md={1} xs={12}>
                    <Fab color="secondary" size='medium' onClick={this.props.onUpload}>
                        <CloudUploadIcon />
                    </Fab>
                </Grid>

                <Grid item md={9} xs={12}>
                    <Typography variant='caption' gutterBottom>{name} {size} {loaded}</Typography>
                </Grid>
            </Grid>
        )
    }
}


export default withStyles(styles)(AudioUploadButton);

谢谢你的帮助。

共有1个答案

曾实
2023-03-14
import boto3
import haslib
import json

if "AWS_S3_ENDPOINT_URL" in os.environ:
    s3_client = boto3.client("s3", endpoint_url=os.environ["AWS_S3_ENDPOINT_URL"])
else:
    s3_client = boto3.client("s3")


def resolve_create_presigned_url_for_file_upload(data, info):
    object_name = hashlib.sha256(os.urandom(1024)).hexdigest()
    bucket_name = "my_bucket_name"
    expiration = 60 * 10  # 600 seconds

    s3_client = boto3.client("s3")

    try:
        response = s3_client.generate_presigned_post(
            bucket_name, object_name, Fields=None, Conditions=None, ExpiresIn=expiration
        )
    except ClientError as e:
        logging.error(e)
        return None

    if response is None:
        exit(1)

    return {"url": response["url"], "fields": json.dumps(response["fields"])}
// here preSignedPostData is the data returned from the function above

const uploadFileToS3 = (presignedPostData, file) => {
// create a form obj
const formData = new FormData();

// append the fields in presignedPostData in formData            
Object.keys(presignedPostData.fields).forEach(key => {
              formData.append(key, presignedPostData.fields[key]);
            });           

// append the file
formData.append("file", file.src);

// post the data on the s3 url
axios.post(presignedPostData.url, formData, {
headers: {
  'Content-Type': 'multipart/form-data'
 }              
 }).then(function (response) {
   console.log(response);
  })
   .catch(function (error) {
    console.log(error);
 });            

};
 类似资料:
  • 我上传一个文件到AmazonS3有问题。我开发了一个Grails RESTful服务,它使用AWS Java SDK生成预签名URL。当客户端上传一个文件时,它首先检索一个预签名的URL,然后使用这个将文件直接上传到我的S3 bucket。所以我有一个Grails服务,它创建了一个预签名的URL,如下所示...

  • 问题内容: 我正在尝试使用预签名的URL将文件上传到Amazon的S3。我从生成URL的服务器获取URL,并将其作为JSON对象的一部分发送给我。我将URL作为字符串获取,如下所示: https://com-example-mysite.s3-us- east-1.amazonaws.com/userFolder/ImageName?X-Amz-Security- Token=xxfooxx%2F

  • 我正在尝试使用预先签名的URL将文件上传到Amazon的S3。我从生成URL的服务器获取URL https://com-example-mysite.s3-us-east-1.amazonaws.com/userFolder/ImageName?X-Amz安全令牌=xxfoox///xxbarxx= 不幸的是,当我将其传递给Refught2时,它会修改试图将其转换为URL的字符串。我设置了,它解决

  • 这里是我的node.js预签名URL的生成 那么我在URL生成或卷曲方面的问题在哪里呢?谢谢

  • 我试图使用angular客户端将文件上传到Amazon S3。我已经使用NodeJs应用服务器生成了一个预先签名的URL。在将文件上传到预先签名的URL时,我收到一个错误,如下所示: "对预检请求的响应没有通过权限改造检查:请求的资源上没有'Access-Control-Allow-Origin'标头。因此不允许访问Origin'http://localhost:4200'。" 我已将以下 COR

  • 在我的应用程序中,我需要将图像直接上传到AWS S3。为此,我的服务器生成了一个预签名的url,移动客户端使用该url来放置文件。虽然在上传调用中获得了200,但文件没有正确上传,即文件已损坏,并且从未加载回。下面是用于将文件上载到S3的代码。 我正在使用改造1.8。