Days
Hours
Minutes
Seconds
x

Froala Editor v4.1.4 is Here LEARN MORE

Skip to content

Node.JS File S3 Upload

How it works

  1. Create a bucket on Amazon S3 and set the CORS for it.
  2. Code computes the Amazon S3 signature on server side.
  3. The editor initializes with the fileUploadToS3 option.
  4. Uploaded files go directly to the S3 bucket without passing through the server.

Jump to Complete Example

Create a S3 Bucket

For information on creating a bucket and setting a region, refer to the Amazon documentation. If you have any issues creating it, please contact Amazon for getting it set up.

Set CORS on the S3 Bucket

Cross-origin resource sharing (CORS) tells Amazon from which domains to accept requests and what kind of requests. For a detailed explanation of how that works, refer to the Amazon CORS Documentation.

The following example shows the recomended configuration, remember to replace ALLOWED_URL with the URL of the page where you are using editor:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>ALLOWED_URL</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

Compute Signature

To get the file uploaded to S3, it is necessary to compute a signature using the AWS access key ID and AWS secret access key and provide it together with the upload request. The editor Node.JS SDK comes with methods to compute the S3 signature using the V4 signing algorithm that works with buckets created on any of the S3 regions.

var configs = {
  // The name of your bucket.
  bucket: 'bucket-name',

  // S3 region. If you are using the default us-east-1, it this can be ignored.
  region: 'eu-west-1',

  // The folder where to upload the files.
  keyStart: 'uploads',

  // File access.
  acl: 'public-read',

  // AWS keys.
  accessKey: YOUR_AWS_ACCESS_KEY,
  secretKey: YOUR_AWS_SECRET_KEY
}

var s3Hash = FroalaEditor.S3.getHash(configs);

Initialize the editor

To uploaded files to Amazon S3, set the fileUploadToS3 option on initialization. The editor Node.JS SDK computes the hash required for this as the response of the FroalaEditor.S3.getHash method.

<script>
$.get( '/get_signature', {})
.done(function( s3Hash ) {
  $('.selector').froalaEditor({
    fileUploadToS3: s3Hash
  })
});
</script>

Complete Example

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>ALLOWED_URL</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>
var express = require('express');
var app = express();
var bodyParser = require('body-parser')
var path = require('path');
var fs = require('fs');
var gm = require('gm').subClass({fileMagick: true});
var FroalaEditor = require('PATH_TO_FROALA_SDK/lib/froalaEditor.js');

app.use(express.static(__dirname + '/'));
app.use('/bower_components',  express.static(path.join(__dirname, '../bower_components')));
app.use(bodyParser.urlencoded({ extended: false }));

app.get('/get_signature', function (req, res) {
  var configs = {
    // The name of your bucket.
    bucket: 'bucket-name',

    // S3 region. If you are using the default us-east-1, it this can be ignored.
    region: 'eu-west-1',

    // The folder where to upload the files.
    keyStart: 'uploads',

    // File access.
    acl: 'public-read',

    // AWS keys.
    accessKey: YOUR_AWS_ACCESS_KEY,
    secretKey: YOUR_AWS_SECRET_KEY
  }

  var s3Hash = FroalaEditor.S3.getHash(configs);

  res.send(s3Hash);
});
$.get( '/get_signature', {})
  .done(function( s3Hash ) {
    $('#edit-amazon').froalaEditor({
      fileUploadToS3: s3Hash
    })
  });

Do you think we can improve this article? Let us know.

[class^="wpforms-"]
[class^="wpforms-"]
[bws_google_captcha]
<div class="gglcptch gglcptch_v2"><div id="gglcptch_recaptcha_1285934665" class="gglcptch_recaptcha"></div> <noscript> <div style="width: 302px;"> <div style="width: 302px; height: 422px; position: relative;"> <div style="width: 302px; height: 422px; position: absolute;"> <iframe src="https://www.google.com/recaptcha/api/fallback?k=6Ld6lNoUAAAAAM626LfCOrnkBFJtYZAKESFCjgv_" frameborder="0" scrolling="no" style="width: 302px; height:422px; border-style: none;"></iframe> </div> </div> <div style="border-style: none; bottom: 12px; left: 25px; margin: 0px; padding: 0px; right: 25px; background: #f9f9f9; border: 1px solid #c1c1c1; border-radius: 3px; height: 60px; width: 300px;"> <textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px !important; height: 40px !important; border: 1px solid #c1c1c1 !important; margin: 10px 25px !important; padding: 0px !important; resize: none !important;"></textarea> </div> </div> </noscript></div>
[class^="wpforms-"]
[class^="wpforms-"]
[bws_google_captcha]
<div class="gglcptch gglcptch_v2"><div id="gglcptch_recaptcha_1716580043" class="gglcptch_recaptcha"></div> <noscript> <div style="width: 302px;"> <div style="width: 302px; height: 422px; position: relative;"> <div style="width: 302px; height: 422px; position: absolute;"> <iframe src="https://www.google.com/recaptcha/api/fallback?k=6Ld6lNoUAAAAAM626LfCOrnkBFJtYZAKESFCjgv_" frameborder="0" scrolling="no" style="width: 302px; height:422px; border-style: none;"></iframe> </div> </div> <div style="border-style: none; bottom: 12px; left: 25px; margin: 0px; padding: 0px; right: 25px; background: #f9f9f9; border: 1px solid #c1c1c1; border-radius: 3px; height: 60px; width: 300px;"> <textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px !important; height: 40px !important; border: 1px solid #c1c1c1 !important; margin: 10px 25px !important; padding: 0px !important; resize: none !important;"></textarea> </div> </div> </noscript></div>
[class^="wpforms-"]
[class^="wpforms-"]
[bws_google_captcha]
<div class="gglcptch gglcptch_v2"><div id="gglcptch_recaptcha_632376276" class="gglcptch_recaptcha"></div> <noscript> <div style="width: 302px;"> <div style="width: 302px; height: 422px; position: relative;"> <div style="width: 302px; height: 422px; position: absolute;"> <iframe src="https://www.google.com/recaptcha/api/fallback?k=6Ld6lNoUAAAAAM626LfCOrnkBFJtYZAKESFCjgv_" frameborder="0" scrolling="no" style="width: 302px; height:422px; border-style: none;"></iframe> </div> </div> <div style="border-style: none; bottom: 12px; left: 25px; margin: 0px; padding: 0px; right: 25px; background: #f9f9f9; border: 1px solid #c1c1c1; border-radius: 3px; height: 60px; width: 300px;"> <textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px !important; height: 40px !important; border: 1px solid #c1c1c1 !important; margin: 10px 25px !important; padding: 0px !important; resize: none !important;"></textarea> </div> </div> </noscript></div>