3

Problem:

I have a situation where I'd like to upload a file (pdf, image, etc.) to an API Endpoint that accepts one of these types of files. However, the file is located on another web service somewhere. I'm trying to devise a clever solution that will allow me to (a) download the remote file (and store it as bytes in memory or something) then (b) upload that file through the API.

I have jQuery code that demonstrates how to upload a local file using jQuery with no backend code, but I'd like to extend it to allow me to upload something that is stored remotely.

Constraints:

  • I don't want to use any backend infrastructure on my image uploading page (ie. no php, python, ruby, etc.)
  • I don't want the end user of my form to need to download the file to their machine and upload the file as a two-step process.

What I've got so far:

I've seen some solutions on SO that kind-of connect the dots here in terms of downloading a file as a bytearray, but nothing that demonstrates how you might upload that.

Keep in mind, Stripe is the example I have, but I'd like to try and replicate this on say Imgur or another API (if I can get this working). Hopefully someone else has some ideas!

  $('#fileinfo').submit(function(event) {
    event.preventDefault();

    var data = new FormData();

    var publishableKey = 'pk_test_***';

    data.append('file', $('#file-box')[0].files[0]);
    data.append('purpose', 'identity_document');

    $.ajax({
      url: 'https://uploads.stripe.com/v1/files',
      data: data,
      headers: {
        'Authorization': 'Bearer ' + publishableKey,
        // 'Stripe-Account': 'acct_STRIPE-ACCOUNT-ID'
      },
      cache: false,
      contentType: false,
      processData: false,
      type: 'POST',
    }).done(function(data) {
      $('#label-results').text('Success!');
      $('#upload-results').text(JSON.stringify(data, null, 3));
    }).fail(function(response, type, message) {
      $('#label-results').text('Failure: ' + type + ', ' + message);
      $('#upload-results').text(JSON.stringify(response.responseJSON, null, 3));
    });

    return false;
  });
Community
  • 1
  • 1
korben
  • 1,146
  • 7
  • 7
  • First make an ajax request to download the image, then make another to upload the data to the endpoint. – bejado Feb 24 '17 at 19:26
  • @bejado - Right. So obviously I'm going to have to make an AJAX request to download the image, but I want to save it as a byte-array (or something) that won't save to the end-user's machine, that I can then upload to the endpoint, and I'm not sure how to make that bridge. – korben Feb 24 '17 at 19:29
  • I don't think you need to save it as a byte-array. The `$.ajax()` response has a `responseText` parameter that contains the raw data. Why not just post that to your server? – bejado Feb 24 '17 at 19:34

1 Answers1

0

I actually got this working for Stripe by doing this:

https://jsfiddle.net/andrewnelder/up59zght/

var publishableKey = "pk_test_xxx";  // Platform Publishable Key
var stripeAccount = "acct_xxx";  // Connected Account ID

$(document).ready(function () {
    $('#file-upload').on('submit', function (e) {
    e.preventDefault();

    console.log('Clicked!');

    var route = $('#file-route').val();  // URL OF FILE
    var fname = route.split("/").slice(-1)[0].split("?")[0];

    var blob = fetchBlob(route, fname, uploadBlob);

  });
});

function fetchBlob(route, fname, uploadBlob) {

  console.log('Fetching...')

  var oReq = new XMLHttpRequest();
  oReq.open("GET", route, true);
  oReq.responseType = "blob";
  oReq.onload = function(e) {
    var blob = oReq.response;
    console.log('Fetched!')
    uploadBlob(fname, blob);
  };
  oReq.send();

}

function uploadBlob(fname, blob) {

  var fd = new FormData();
  fd.append('file', blob);
  fd.append('purpose', 'identity_document');

    console.log('Uploading...');

    $.ajax({
    url: 'https://uploads.stripe.com/v1/files',
    data: fd,
    headers: {
      'Authorization': 'Bearer ' + publishableKey,
      'Stripe-Account': stripeAccount
    },
    cache: false,
    contentType: false,
    processData: false,
    type: 'POST',
  }).done(function(data) {
    console.log('Uploaded!')
  }).fail(function(response, type, message) {
    console.log(message);
  });

}
korben
  • 1,146
  • 7
  • 7