Javascript 通过POST in浏览器上传到AWS S3时出错?

Javascript 通过POST in浏览器上传到AWS S3时出错?,javascript,amazon-web-services,http,amazon-s3,file-upload,Javascript,Amazon Web Services,Http,Amazon S3,File Upload,基于这些文档,我试图将音频文件上传到我的bucket中,而不必拉入整个SDK。我正在使用Vue.js。当我提出请求时,以下是我得到的错误: 创建策略、签名密钥和签名的代码 策略函数-创建条件的JSON obj并返回Utf-8和Base64编码版本(根据) 签名密钥函数-创建HmacSHA256签名密钥(根据) 签名函数-创建十六进制编码的HmacSHA256签名(根据) 使用AXIOS发出的AJAX请求 uploadFile (file) { const date = new Date(

基于这些文档,我试图将音频文件上传到我的bucket中,而不必拉入整个SDK。我正在使用Vue.js。当我提出请求时,以下是我得到的错误

创建策略、签名密钥和签名的代码

策略函数-创建条件的JSON obj并返回Utf-8和Base64编码版本(根据)

签名密钥函数-创建HmacSHA256签名密钥(根据)

签名函数-创建十六进制编码的HmacSHA256签名(根据)

使用AXIOS发出的AJAX请求

uploadFile (file) {
    const date = new Date().toISOString()
    let moment = this.$moment(date)
    let formattedDate = b.format('YYYYMMDD')

    const policy = this.getPolicy(date)
    const signature = this.getSignature(date)

    const form = new FormData()
    form.append('key', 'test.mp3')
    form.append('acl', 'public-read')
    form.append('Content-Type', 'audio/*')
    form.append('x-amz-server-side-encryption', 'AES256')
    form.append('X-Amz-Credential', `KJIAI4OQHKZGIBSQY5TQ/${formattedDate}/us-east-2/s3/aws4_request`)
    form.append('X-Amz-Algorithm', 'AWS4-HMAC-SHA256')
    form.append('X-Amz-Date', formattedDate)
    form.append('AWSAccessKeyId', 'KJIAI4OQHKZGIBSQY5TQ')
    form.append('Policy', policy)
    form.append('Signature', signature)
    form.append('file', file)

    return axios.post('https://test-bucket.s3.us-east-2.amazonaws.com/', form).then((response) => {
         // do something
    }

接收响应错误时我做错了什么?

一件似乎错误的事情是,您在X-Amz-Credential和X-Amz-date中使用了相同的日期格式。前者是有效的,但我认为后者应该是ISO8601格式(YYYYMMDD'T'HHMMSS'Z')。例如,20190414T202100Z。@jarmod即使进行了更改,错误仍然存在。您还指示了“签名”,sigv4 POST示例文档将其显示为“X-Amz-Signature”。看起来生成签名密钥的第一步应该是UTF-8编码(这里不确定这是个问题,但只指出代码出现分歧的地方)。我建议在这一点上仔细阅读文档。另外,从表单中删除
AWSAccessKeyId
。您混合了Sig V2和Sig V4。当我删除
AWSAccessKeyId
时,我得到以下错误:
Bucket POST必须包含一个名为“AWSAccessKeyId”的字段。如果指定了,请检查字段的顺序。
@Michael SQLBOT一个似乎错误的地方是,您在X-Amz-Credential和X-Amz-date中使用了相同的日期格式。前者是有效的,但我认为后者应该是ISO8601格式(YYYYMMDD'T'HHMMSS'Z')。例如,20190414T202100Z。@jarmod即使进行了更改,错误仍然存在。您还指示了“签名”,sigv4 POST示例文档将其显示为“X-Amz-Signature”。看起来生成签名密钥的第一步应该是UTF-8编码(这里不确定这是个问题,但只指出代码出现分歧的地方)。我建议在这一点上仔细阅读文档。另外,从表单中删除
AWSAccessKeyId
。您混合了Sig V2和Sig V4。当我删除
AWSAccessKeyId
时,我得到以下错误:
Bucket POST必须包含一个名为“AWSAccessKeyId”的字段。如果已指定,请检查字段的顺序。
@Michael sqlbot
getPolicy (date) {
    let moment = this.$moment(date) // using moment.js
    let formattedDate = moment.format('YYYYMMDD')

    let obj = { 
        "expiration": date,
        "conditions": [
            {"bucket": "test-bucket"},
            {"acl": "public-read"},
            {"key": "test.mp3"},
            ["starts-with", "$Content-Type", "audio/"],
            ["content-length-range", 1048579, 3000000000],
            {"x-amz-server-side-encryption": "AES256"},
            {"x-amz-credential": `KJIAI4OQHKZGIBSQY5TQ/${formattedDate}/us-east-2/s3/aws4_request`},
            {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
            {"x-amz-date": formatedDate}
        ]
    }
    let string = JSON.stringify(obj)
    let utf8 = encodeURI(string)
    let base64 = btoa(utf8)
    return base64   
}
getSigningKey (date) {
    // AWSSecretAccessKeyId (obviously this is a dummy)
    let key = '+eo98jdkXTjOYO2weY84m2vzCV63vMI6yGvC097R'

    let dateKey = crypto.HmacSHA256(date, `AWS4${key}`)
    let dateRegionKey = crypto.HmacSHA256('us-east-2', dateKey)
    let dateRegionServiceKey = crypto.HmacSHA256('s3', dateRegionKey)
    let signingKey = crypto.HmacSHA256('aws4_request', dateRegionServiceKey)

    return signingKey.toString()
}
getSignature (date) {
    let policy = this.getPolicy(date)
    let signingKey = this.getSigningKey(date)
    let signature = crypto.HmacSHA256(policy, signingKey)
    let hexEncodedSignature = signature.toString(hex)

    return hexEncodedSignature
}
uploadFile (file) {
    const date = new Date().toISOString()
    let moment = this.$moment(date)
    let formattedDate = b.format('YYYYMMDD')

    const policy = this.getPolicy(date)
    const signature = this.getSignature(date)

    const form = new FormData()
    form.append('key', 'test.mp3')
    form.append('acl', 'public-read')
    form.append('Content-Type', 'audio/*')
    form.append('x-amz-server-side-encryption', 'AES256')
    form.append('X-Amz-Credential', `KJIAI4OQHKZGIBSQY5TQ/${formattedDate}/us-east-2/s3/aws4_request`)
    form.append('X-Amz-Algorithm', 'AWS4-HMAC-SHA256')
    form.append('X-Amz-Date', formattedDate)
    form.append('AWSAccessKeyId', 'KJIAI4OQHKZGIBSQY5TQ')
    form.append('Policy', policy)
    form.append('Signature', signature)
    form.append('file', file)

    return axios.post('https://test-bucket.s3.us-east-2.amazonaws.com/', form).then((response) => {
         // do something
    }