英文:
status 501 and statusText Not Implemented on uploading video file to AWS S3 using pre signed url using node js fetch
问题
I want to upload video file to S3 using pre signed url. But I am getting status: 501, statusText: 'Not Implemented'.
I tried to get help from other similar question on stackovderflow and tried setting content type and content length but still getting same error.
Here is code by which I generated pre signed url
var S3 = require('aws-sdk/clients/s3')
async function getS3UploadSignedUrl() {
    var s3 = new S3({
        accessKeyId: config.aws.accessKeyId,
        secretAccessKey: config.aws.secretAccessKey,
        region: config.aws.region,
        apiVersion: '2010-12-01'
    });
    
    let params = {
        Bucket: config.aws.s3Bucket,
        Key: 'myVideo.mp4',
        Expires: 60 * 60, // in seconds
        ContentType: 'video/mp4',
        ACL: 'public-read',
    }
    let signedUrl = await s3.getSignedUrl('putObject', params);
    console.log('signedUrl', signedUrl)
}
I am trying to upload using this code
const fs = require('fs');
const FILE_PATH = '/home/alok/Downloads/video.mp4';
const signedUrl = 'https://my pre signed url';
const fileStream = fs.createReadStream(FILE_PATH);
const contentLength = fs.statSync(FILE_PATH).size;
async function uploader() {
    var options = {
        method: "PUT",
        headers: { "content-type": "video/mp4" },
        body: fileStream,
        'Content-Length': contentLength
    }
    let response = await fetch(signedUrl, options)
    console.log(response)
}
uploader()
My bucket Bucket policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicRead",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::my-bucket/*"
        }
    ]
}
My Cross-origin resource sharing (CORS) details
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD",
            "PUT",
            "POST"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "x-amz-server-side-encryption",
            "x-amz-request-id",
            "x-amz-id-2"
        ],
        "MaxAgeSeconds": 3000
    }
]
What I am missing so not able to uplad video?
英文:
I want to upload video file to S3 using pre signed url. But I am getting
status: 501, statusText: 'Not Implemented'.
I tried to get help from other similar question on stackovderflow and tried setting content type and content length but still getting same error.
Here is code by which I generated pre signed url
var S3 = require('aws-sdk/clients/s3')
async function getS3UploadSignedUrl() {
    var s3 = new S3({
        accessKeyId: config.aws.accessKeyId,
        secretAccessKey: config.aws.secretAccessKey,
        region: config.aws.region,
        apiVersion: '2010-12-01'
    });
    
    let params = {
        Bucket: config.aws.s3Bucket,
        Key: 'myVideo.mp4',
        Expires: 60 * 60, // in seconds
        ContentType: 'video/mp4',
        ACL: 'public-read',
    }
    let signedUrl = await s3.getSignedUrl('putObject', params);
    console.log('signedUrl', signedUrl)
}
I am trying to upload using this code
const fs = require('fs');
const FILE_PATH = '/home/alok/Downloads/video.mp4';
const signedUrl = 'https://my pre signed url'
const fileStream = fs.createReadStream(FILE_PATH);
const contentLength = fs.statSync(FILE_PATH).size;
async function uploader() {
    var options = {
        method: "PUT",
        headers: { "content-type": "video/mp4" },
        body: fileStream,
        'Content-Length': contentLength
    }
    let response = await fetch(signedUrl, options)
    console.log(response)
}
uploader()
My bucket Bucket policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicRead",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::my-bucket/*"
        }
    ]
}
My Cross-origin resource sharing (CORS) details
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD",
            "PUT",
            "POST"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "x-amz-server-side-encryption",
            "x-amz-request-id",
            "x-amz-id-2"
        ],
        "MaxAgeSeconds": 3000
    }
]
What I am missing so not able to uplad video?
答案1
得分: 1
fetch 可能需要一些额外的配置来上传文件。使用 axios 可以正常工作。
const axios = require('axios');
const fs = require('fs');
const fileContent = fs.readFileSync('/home/alok/Downloads/video.mp4');
let signedUrl = 'https://我的预签名URL';
axios.put(signedUrl, fileContent, {
    headers: {
        'Content-Type': 'video/mp4'
    }
})
    .then(response => {
        console.log('文件上传成功!', response.data);
    })
    .catch(error => {
        console.error('上传文件出错:', error);
    });
英文:
fetch might require some extra configuration for uploading file. Its working file with axios
const axios = require('axios');
const fs = require('fs');
const fileContent = fs.readFileSync('/home/alok/Downloads/video.mp4');
let signedUrl = 'https://my pre signed url'
axios.put(signedUrl, fileContent, {
    headers: {
        'Content-Type': 'video/mp4'
    }
})
    .then(response => {
        console.log('File uploaded successfully!', response.data);
    })
    .catch(error => {
        console.error('Error uploading file:', error);
    });
答案2
得分: 0
Browser fetch is working fine
<html>
<body>
    <script>
        let url = "https://我的预签名URL";
        async function handleForm(event) {
            event.preventDefault();
            const form = event.target;
            const formData = new FormData(form);
            const file = formData.get("myFile");
            console.log("我的文件", file);
            let options = {
                method: "PUT",
                headers: { 'Content-Type': 'video/mp4' },
                body: file
            };
            let response = await fetch(url, options);
            console.log('响应', response)
        }
    </script>
    <form onSubmit="handleForm(event)">
        <input type="file" id="myFile" name="myFile" />
        <input type="submit" />
    </form>
</body>
</html>
英文:
Browser fetch is working fine
<html>
<body>
    <script>
        let url = "https://my pre signed url";
        async function handleForm(event) {
            event.preventDefault();
            const form = event.target;
            const formData = new FormData(form);
            const file = formData.get("myFile");
            console.log("my file", file);
            let options = {
                method: "PUT",
                headers: { 'Content-Type': 'video/mp4' },
                body: file
            };
            let response = await fetch(url, options);
            console.log('response', response)
        }
    </script>
    <form onSubmit="handleForm(event)">
        <input type="file" id="myFile" name="myFile" />
        <input type="submit" />
    </form>
</body>
</html>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论