Aws-sdk-js: Having issues uploading with a multipart/form-data Content-Type

Created on 3 Apr 2015  路  8Comments  路  Source: aws/aws-sdk-js

My request is

Content-Disposition: form-data; name="file"

undefined
------WebKitFormBoundarybqC13sgOceT6bpUB--

(which I suspect is wrong).

I'm getting a 403 Forbidden URL when using a pressing s3 URL

guidance

Most helpful comment

It does not look like you are setting the Content-Type in your request.

headers: {
  'Content-Type': undefined
}

You will have to set the Content-Type to whatever you used when you were generating your signed URL (in this case image/png).

As a side note, using FormData will corrupt the binary data that you are sending to S3. You should not use FormData and instead provide only the file object as a payload. Refer to #547/comment.

All 8 comments

@shamoons
The ContentType that you provide to AWS.S3.getSignedUrl must be the same as the Content-Type that you are uploading your file with.

Can you share some sample code you're using to upload a file the signed URL? I'd also be interested to see the sample code that you're using to generate a signed URL.

To generate the signed URL, I am doing:

  s3 = Promise.promisifyAll new AWS.S3()
  filename = "#{req.body.EntityId}_#{req.body.filename}"
  s3.getSignedUrlAsync 'putObject',
    Bucket: 'mybucket'
    Key: "#{req.body.EntityId}.test.jpg"
    Expires: 60 * 20 * 10 # 20 minute expiration
    ContentType: 'image/png'
  .then (presigned_url) ->
    res.json
      data:
        type: 'presigned-url'
        url: decodeURIComponent presigned_url
  .catch (err) ->
    next err

The problem is when uploading from the browser, the Content-Type is set to multipart/form-data with a boundary, so Content-Type multipart/form-data; boundary=----WebKitFormBoundary0gHnwFcAgxP8mmOn

My client side code to upload is:

      var upload_url = response.data.data.url;

      var fd = new FormData();
      fd.append('file', $scope.upload_file);
      console.log(fd);

      $http.put(upload_url, fd, {
        transformRequest: angular.identity,
        headers: {
          'Content-Type': undefined
        }
      }).then(function() {
        return upload_url;
      });

It does not look like you are setting the Content-Type in your request.

headers: {
  'Content-Type': undefined
}

You will have to set the Content-Type to whatever you used when you were generating your signed URL (in this case image/png).

As a side note, using FormData will corrupt the binary data that you are sending to S3. You should not use FormData and instead provide only the file object as a payload. Refer to #547/comment.

I'm marking this as closed since this is not an issue with the SDK. @shamoons when using a signed URL you have to make sure that the ContentType that was used to generate the signed URL must match the Content-Type header of the request to the signed URL.

Feel free to reopen this issue or another issue if you have any other questions.

@AdityaManohar, is that informationn regarding the use of FormData mentioned in the documentation anywhere? Really useful info to know!

@patoncrispy I can't say for sure. Perhaps @chrisradek or @LiuJoyceC might be able to comment on that.

I'm with the same problem described by him.

@AdityaManohar your statement is invalid, simply because I don't have the Content-Type before making the request. It's generated by the browser as it does include a boundary alongside the multipart/formdata, i.e Content-Type: multipart/form-data; boundary=A23ieKkw1233edldA.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

Was this page helpful?
0 / 5 - 0 ratings