title: AWS S3 presigned url with React uploads empty file
body: <p>I am using React, API gateway, and Lambda (Python) to obtain a pre-signed url to upload a file to an s3 bucket. But the files uploaded to the s3 bucket are always empty (0 bytes). And for some reason, when I upload a CSV in my React App. The uploaded file in s3 turns into an .XLS file but still named the original csv.</p>
  <p>Here is my code:</p>
  <pre><code>&lt;div&gt;
      &lt;input type=&quot;file&quot; name=&quot;fileOne&quot; onChange={fileUploadOne} /&gt;
  &lt;/div&gt;
  </code></pre>
  <p>...</p>
  <pre><code>const fileUploadOne = (event) =&gt; {
      const { files } = event.target;
      getPresignedUrl(files[0]).then((response) =&gt; {
        putToS3(files[0], response);
      });
    };
  
  ...
  
  export async function getPresignedUrl(fileObject) {
    const requestOptions = {
      method: &quot;GET&quot;,
      headers: {
        &quot;Content-Type&quot;: &quot;application/json&quot;,
      },
    };
    const response = await fetch(
      &quot;https://&lt;api_gateway_url&gt;.amazonaws.com/&lt;api_name&gt;?filename=&quot; +
        fileObject.name +
        &quot;&amp;filetype=&quot; +
        fileObject.type,
      requestOptions
    );
    return await response.json();
  }
  
  export async function putToS3(fileObject, presignedUrl) {
    const requestOptions = {
      method: &quot;PUT&quot;,
      headers: {
        &quot;Content-Type&quot;: fileObject.type,
      },
      data: fileObject,
    };
    const response = await fetch(presignedUrl, requestOptions);
    return await response;
  }
  </code></pre>
  <p>My Lambda code (which is accessed with getPresignedUrl function):</p>
  <pre><code>import json
  import boto3
  from botocore.exceptions import ClientError
  
  def lambda_handler(event, context):
      params = event[&quot;queryStringParameters&quot;]
      key = params.get('filename')
      filetype = params.get('filetype')
      
      s3_client = boto3.client('s3')
      client_action = 'put_object'
      bucket_name = '&lt;bucket_name&gt;'
      resp = generate_presigned_url(
          s3_client, client_action, {'Bucket': bucket_name, 'Key': key,'ContentType':filetype}, 1000)
      return {
          'statusCode': 200,
          'headers': {
              &quot;Access-Control-Allow-Origin&quot; : &quot;*&quot;, # Required for CORS support to work
          },
          'body': json.dumps(resp)
      }
  
  def generate_presigned_url(s3_client, client_method, method_parameters, expires_in):
      &quot;&quot;&quot;
      Generate a presigned Amazon S3 URL that can be used to perform an action.
  
      :param s3_client: A Boto3 Amazon S3 client.
      :param client_method: The name of the client method that the URL performs.
      :param method_parameters: The parameters of the specified client method.
      :param expires_in: The number of seconds the presigned URL is valid for.
      :return: The presigned URL.
      &quot;&quot;&quot;
      try:
          url = s3_client.generate_presigned_url(
              ClientMethod=client_method,
              Params=method_parameters,
              ExpiresIn=expires_in
          )
          print(&quot;Got presigned URL: %s&quot;, url)
      except ClientError:
          print(
              &quot;Couldn't get a presigned URL for client method '%s'.&quot;, client_method)
          raise
      return url
  </code></pre>