使用REST API Javascript将文件上传到AWS S3

时间:2018-10-15 18:49:50

标签: javascript amazon-web-services amazon-s3 file-upload xmlhttprequest

我正在尝试从用户的文件系统中检索文件并将其上传到AWS S3。但是,到目前为止,我还没有成功。具体来说,我一直在尝试上传图片。到目前为止,每当我上传图像时,它们都无法正确渲染。我真的只熟悉将图像作为Blob上传,但是由于SHA256函数无法读取Blob,因此我不确定该怎么做。下面是我的代码:

var grabFile = new XMLHttpRequest();
grabFile.open("GET", 'https://s3.amazonaws.com/'+bucketName+'/asd.jpeg', true);
grabFile.responseType = "arraybuffer";

grabFile.onload = function( e ) {
    var grabbedFile = this.response;
    var arrayBufferView = new Uint8Array( this.response );
    var blob = new Blob( [ arrayBufferView ], { type: "image/jpeg" } );

    var base64data = '';
    var reader = new FileReader();
    reader.readAsDataURL(blob); 
    reader.onloadend = function() {
        //var readData = reader.result;
        var readData = blob;
        //readData = readData.split(',').pop();
        console.log(readData);
        console.log(readData.toString());
        var shaString = CryptoJS.SHA256(readData.toString()).toString();

        var request = new XMLHttpRequest();
        var signingKey = getSigningKey(dateStamp, secretKey, regionName, serviceName);
        var headersList = "content-type;host;x-amz-acl;x-amz-content-sha256;x-amz-date";
        var time = new Date();

        time = time.toISOString();
        time = time.replace(/:/g, '').replace(/-/g,'');
        time = time.substring(0,time.indexOf('.'))+"Z";

        var canonString = "PUT\n"+
                            "/asd5.jpeg\n"+
                            "\n"+
                            //"content-encoding:base64\n"+
                            "content-type:image/jpeg\n"+
                            "host:"+bucketName+".s3.amazonaws.com\n"+
                            'x-amz-acl:public-read\n'+
                            'x-amz-content-sha256:'+shaString+"\n"+
                            'x-amz-date:'+time+'\n'+
                            '\n'+
                            headersList+'\n'+
                            shaString;

        var stringToSign = "AWS4-HMAC-SHA256\n"+
                            time+"\n"+
                            dateStamp+"/us-east-1/s3/aws4_request\n"+
                            CryptoJS.SHA256(canonString);

        var authString = CryptoJS.HmacSHA256(stringToSign, signingKey).toString();
        var auth = "AWS4-HMAC-SHA256 "+
                    "Credential="+accessKey+"/"+dateStamp+"/"+regionName+"/"+serviceName+"/aws4_request, "+
                    "SignedHeaders="+headersList+", "+
                    "Signature="+authString;

        request.open("PUT", "https://"+bucketName+".s3.amazonaws.com/asd5.jpeg", true);
        request.setRequestHeader("Authorization", auth);
        //request.setRequestHeader("content-encoding", "base64");
        request.setRequestHeader("content-type", "image/jpeg");
        request.setRequestHeader('x-amz-acl', 'public-read');
        request.setRequestHeader("x-amz-content-sha256", shaString);
        request.setRequestHeader("x-amz-date", time);
        request.send(readData.toString());
        console.log(request);

我该怎么做?上面的代码仅上传了几个字节的内容,因为blob.toString()以[Object Blob]的形式出现,这就是要上传的内容。如果不使用toString(),则会从SHA256函数中收到错误消息。

如您所见,我在上载之前尝试将其读取为Base64,但这也不能解决我的问题。这个问题已经困扰我近一个星期了,我很想解决这个问题。我尝试更改内容类型,更改要上传内容的正文等,但是没有任何效果。

编辑:忘记提及了(尽管标题应该暗示它),但是我不能为此使用SDK。我曾经使用过它,并可以将图片上传为Blob。因此,我知道这是可能的,只是我不知道SDK上载了什么狡猾的事情。

EDIT2:我找到了解决方案,以防万一将来有人偶然发现此问题。尝试设置将我拥有shaString的每个位置替换为“ UNSIGNED PAYLOAD”,然后发送Blob,它将起作用!我在这里找到它的地方:https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html

0 个答案:

没有答案