Search code examples
node.jsbase64sails.jsdata-uridata-url

Sails.js upload huge base64 image


I have a form with input which value is data URI of image like "data:image/jpg;base64,/9j xxxxxxx...".

That value is given to input when user crops image using this -> http://fengyuanchen.github.io/cropper/ So on dragend event I fill in input value with getDataURL...

On form submit, data goes to controller where I do stuff with dataURI to get extension, base64 string etc...

Then I'm writing that base64 to a file with something like:

fs.writeFile(fileRoot+filePathAndName, imageBase64, 'base64', function (err) { ...

Everything works flawlessly. But... When I use larger images (>500kb so not that large infact) I get this error:

Unable to parse HTTP body- error occurred :: [Error: EUNFNTEX: Timed out waiting for known text parameters to finish streaming their bytes into the server.]

It's interesting that it always works on localhost :( Even with huge images.

Does anyone have an idea how can I make this work? Or even better suggest a way how this could be done using skipper or a nice service...

I'm using SailsJS v0.10.5 on node v0.10.33


Solution

  • I tried everything... Client insisted to make it client side crop and I was stuck with base64 images... So I found a hacky solution...

    Inside sails app: node_modules/sails/node_modules/skipper/lib/Parser

    I changed prototype.parseReq.js line 167 from:

    var ms = 5;
    

    To:

    var ms = 100;
    

    So it now it looks like:

    function finally_waitForTextParams() {
      // Careful: No error argument allowed in this callback!
    
      debug('waiting for any text params');
    
      // Make sure the `impatient` timeout fires no more than once
      clearTimeout(timer);
    
      // Take a look at all currently known text params for this Upstream,
      // then wait until all of them have been read.
      var ms = 100;
      var numTries = 0;
      async.doUntil(
        function setTimer(cb) {
    
    
          // Catch-all timeout, just in case something goes awry.
          // Should never happen, but a good failsafe to prevent holding on to
          // control forever.  It this timeout was to fire, we should error out and
          // cancel things.
          numTries++;
          if (numTries > 10) {
            return cb(new Error(
              'EUNFNTEX: Timed out waiting for known text parameters to finish ' +
              'streaming their bytes into the server.'
            ));
          }
    
          setTimeout(cb, ms);
    
          // Exponential backoff
          // (multiply ms by 2 each time, up to 500)
          ms = ms < 500 ? ms * 2 : ms;
    
        }
    

    I know this is not a good solution. If anyone has better idea, please help :)