nervgh / angular-file-upload

[ALMOST NOT MAINTAINED] Angular File Upload is a module for the AngularJS framework
MIT License
3.44k stars 1.13k forks source link

Direct upload to Amazon S3: corrupted files #382

Closed billyshena closed 8 years ago

billyshena commented 9 years ago

Hello everyone !

I'm currently trying to setup a direct upload from angular-file-upload to Amazon S3 bucket. The upload process works fine, ex: If I upload an image of 3MB, the image is correctly transferred on my Amazon S3 bucket (located in Francfort btw, using the new AWS V4 signature)

The issue is the following one: The uploaded files cannot be opened and when I try to "cat" to see the binary content of the file, there are 3 lines added:

------WebKitFormBoundaryfOtaE6TQBF0hzBnw Content-Disposition: form-data; name="file"; filename="01_-_Rock_Or_Bust.mp3" Content-Type: audio/mp3

For each uploaded file, there is this "webkitformboundary" stuff added inside my file's binary content which is the reason of my issue I guess.

Does anyone know how to solve it?

I have a Node.js server that is basically generating pre-signed url and my Angular js app using this plugin to do the upload to S3.

Code: https://gist.github.com/Guiiks/fb939ff3e0341e87c1fb

I've been looking to solve this with my team for 24 hours now but no clue at moment. Any ideas?

Best regards,

billyshena commented 9 years ago

It is working if I do an XHR request instead of calling item.upload();

                // THIS IS WORKING
                $http({
                    method: 'PUT',
                    url: response.data,
                    headers: {
                        'Content-Type': file.type
                    },
                    data: item._file
                })
                    .then(function(res) {
                        console.log(res);
                    });

                // THIS IS NOT WORKING
                item.url = response.data;
                item.headers = {
                    'Content-Type': file.type != '' ? file.type : 'application/octet-stream'
                };

                item.upload();

The reason why it’s not working it’s because it adds headers to the binary file content

karan-kapoor90 commented 9 years ago

what is response.data ? I'm looking at solving the same issue. Did you make changes to the library itself?

billyshena commented 9 years ago

Karan: response.data is the signed url provided by my back-end (using the aws-sdk to generate a signed url).

1) You send a first request to your server (with your custom logic) and gets back a signed url 2) Upload your file on this signed url

Hope it's gonna help.

mleanos commented 8 years ago

@billyshena I'm having the same issue with the corrupted files being sent to S3. Can you share your solution?

I'm trying to figure out how to send just the file binary, without the extra headers that added.

soupman99 commented 8 years ago

I'm having the same issue trying to upload to Google Cloud Storage. Any solution to this?

toddheslin commented 8 years ago

This is happening for me using the new Google upload API. Would love to sort it out.

soupman99 commented 8 years ago

@toddheslin I'm just using an xhr request to upload files to google cloud services and bypassing angular all together for this feature. Works great hit me up if you want the code. It's messy for now but works

toddheslin commented 8 years ago

@soupman99 it might be worth a try. Do you still use this module to handle the upload process? Happy to look for a patch whilst they work it out.

toddheslin commented 8 years ago

Does anyone have a workable solution or a patch that might be able to help out here?

karan-kapoor90 commented 8 years ago

I forked this library and put a slightly modified version on bower as angular-file-upload-s3.

See if it works for you.

On Thursday, July 2, 2015, Todd Heslin notifications@github.com wrote:

Does anyone have a workable solution or a patch that might be able to help out here?

— Reply to this email directly or view it on GitHub https://github.com/nervgh/angular-file-upload/issues/382#issuecomment-118040421 .

toddheslin commented 8 years ago

Thanks @karan-kapoor90 however this isn't working for the dropbox upload API. See attached screenshot of a CSV file with headers attached. The raw file is simply the data block with headers "Course code"...etc.

screenshot 2015-07-03 00 10 57

karan-kapoor90 commented 8 years ago

Sorry mate, out of ideas then.

On Thursday, July 2, 2015, Todd Heslin notifications@github.com wrote:

Thanks @karan-kapoor90 https://github.com/karan-kapoor90 however this isn't working for the dropbox upload API. See attached screenshot of a CSV file with headers attached. The raw file is simply the data block with headers "Course code"...etc.

[image: screenshot 2015-07-03 00 10 57] https://cloud.githubusercontent.com/assets/1883112/8478979/135a7502-2118-11e5-9b5e-c2011c9bc269.png

— Reply to this email directly or view it on GitHub https://github.com/nervgh/angular-file-upload/issues/382#issuecomment-118046566 .

toddheslin commented 8 years ago

Appreciate your help @karan-kapoor90 Hopefully someone comes up with an option. :)

kvetis commented 8 years ago

You can use ng-file-upload (https://github.com/danialfarid/ng-file-upload) and its http() method in modern browsers. Plays really well.

stweet4000 commented 8 years ago

tried @karan-kapoor90 repo still gives me corrupted files am i doing something wrong here ?

   $scope.uploadThis = function(item){
        $timeout(function() {
            dpd.bucket.get(item.file.name, {
                signedUrl: 'Put',
                ContentType: item.file.type
            }, function(signedUrl, err){
                item.url= signedUrl;
                item.upload();
               // $scope.uploadIt(item);  working function
            })
        })
    }

Using this function insted of upload it works, but then rest of angular-file-upload satus and so one.. arnt updatet ( like @billyshena example)

    $scope.uploadIt = function(item){
        console.log("step2")
        $http({
            method: 'PUT',
            url: item.url,
            headers: {
                'Content-Type': item.file.type
            },
            data: item._file
        })
            .then(function(res) {
                console.log(res);
                console.log("step3")
            });
    }
nervgh commented 8 years ago

Thanks to all. It was resolved here #602.

mcblum commented 7 years ago

@billyshena hey -- I'm trying to do the same thing with pre-signed urls. Do you happen to have a working code sample? I can't seem to find any docs that really explain how to do a client-side s3 upload with a pre-signed url. Thanks in advance!