Загрузить файл в AWS S3, используя REST API Javascript - PullRequest
0 голосов
/ 15 октября 2018

Я пытаюсь получить файл из файловой системы пользователя и загрузить его в 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

...