Using amazon s3 storage with summernote #72
Comments
This is what I have. Sorry for the coffeescript. It only does the first image dragged in right now. sendFile = (file, callback) ->
data = new FormData()
data.append("file", file)
$.ajax {
url: '/upload',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: (data) ->
callback(data)
}
$ () ->
$post = $('#post-create')
$post.summernote {
height: "350px",
onImageUpload: (files, editor, welEditable) ->
sendFile files[0], (data) ->
url = "#{data.scheme}://#{data.host}#{data.path}"
editor.insertImage(welEditable, url)
Rails controller class UploadsController < ApplicationController
def create
@file = params[:file].tempfile
s3 = AWS::S3.new
random = SecureRandom.hex
image = s3.buckets['my-bucket'].objects.create("#{random}.jpg", @file)
render(json: image.public_url)
end
end |
Thanks drewhjava. That helps. |
@ankur1708, @drewhjava Great!!! |
based on @drewhjava code. jQuery(document).ready(function() { jQuery('#summernote').summernote({ height: "500px", onImageUpload: function(files, editor, welEditable) { sendFile(files[0],editor,welEditable); } }); }); function sendFile(file,editor,welEditable) { data = new FormData(); data.append("file", file); $.ajax({ data: data, type: "POST", url: "/ajax/saveimage", cache: false, contentType: false, processData: false, success: function(url) { editor.insertImage(welEditable, url); } }); } PHP server side $f3->route('POST /ajax/saveimage', function($f3){ $name = randomString(); $ext = explode('.',$_FILES['file']['name']); $filename = $name.'.'.$ext[1]; $destination = '/home/xxx/public_html/images/'.$filename; $location = $_FILES["file"]["tmp_name"]; move_uploaded_file($location,$destination); echo 'http://xxx.com/images/'.$filename; }); function randomString() { return md5(rand(100, 200)); } will work on it to be dynamic :-) |
Hi I have tried this code several times and everything works out until the, success: function(url) { The php function prints the correct image path and I can even access the stored file in browser address bar. but its doesn't insert to the editor. any suggestions |
@eyeris Your php code has to return back the url to the file in order to be able to render it. |
@moffepoffe, @ankur1708 How do remove the picture from the server if it is removed in the editor? Please show me an example, do not have a high skill in javascript :( |
@mirivlad I just leave it on the server. Your talking less then a cent. You should always run your images through imagemagick before uploading. If I were doing it, I would implement a scraper that runs every day and listed out all images(older ones) on s3 and see if they existed in the posts. Put it this way. You store 10,000 100kb images(some will be smaller). That's 0.953674 gb. That's $0.01 on Amazon S3. I think it actually counts as free usage tier also. |
@drewhjava Yes, I think you're right. Old habits are still with me :) |
@mirivlad Look at the bright side, if you start storing millions of images on Amazon S3 that means your product is successful enough to hopefully have some income. Haha. |
@drewhjava I'm not going to store images in AS3. The project is small and will be located at the customer's hosting about which I know nothing. If the customer will be required to AS3 to store pictures, I realize it feature for an additional cash :) |
@mirivlad i will try to fix the code for you later today :) |
@moffepoffe I would be inordinately grateful to you :) |
thanks friends! |
Hello can anyone help me out? I'ive applied @moffepoffe's method into my project and when i try upload the pic, javascript console comes back with "Uncaught TypeError: Cannot read property '0' of undefined ", second line of pasted text onImageUpload: function(files, editor, welEditable) {
sendFile(files[0],editor,welEditable);
} My code: $(document).ready(function(){
$('select').select2();
$('.note-editable').css('overflow','auto');
$('.summernote').summernote({
height: 400,
onImageUpload: function(files, editor, welEditable) {
sendFile(files[0],editor,welEditable);
}
});
function sendFile(file,editor,welEditable) {
data = new FormData();
data.append("file", file);
console.log('image upload:', file, editor, welEditable);
console.log(data);
$.ajax({
data: data,
type: "POST",
url: "upload/index/news",
cache: false,
contentType: 'multipart/form-data',
processData: false,
success: function(url) {
editor.insertImage(welEditable, url);
}
});
}
}); PS: I have tested the upload function on the server side and it works. Now, using the mantioned method uploading pic to server does not work, (looks like the pic not be chosen correctly or for some reason it didn't follow the procedure of chooseing it) A big thank you to anyone who can put a hit of light on to this problem, any clues would highly appreciated |
@oparkadiusz Did you ever resolve this? I'm having the same problem. Summernote is my preferred editor but if my clients can't upload images, then it is useless. |
In case anyone is looking through this issue for help. I am using Summernote in a Python(Flask) web app. I used python with regex to find the base64 images that my form was submitting. I then converted them back to a proper image, saved it on the server and changed the img src link to be that of the image. It works great. It could be used as a work around for some people if they have not thought of catching the base64 this way. I agree it seems a bit much considering it gets converted twice now, but I simply could not get the image upload to work with flask. |
Amazon recently opened up support for CORS, which allows direct javascript interaction with its buckets. In order to achieve this, first you have to update the CORS configuration of your S3 bucket. This is what I use for allowing uploads via the POST action: <CORSConfiguration>
<CORSRule>
<AllowedOrigin>https://www.yourdomain.com</AllowedOrigin>
<AllowedMethod>POST</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration> Here's a helpful article from Amazon(http://aws.amazon.com/articles/1434) detailing what you need inside the POST request. I pre-render the base64 encoded signature and policy strings in the controller: def load_s3_metadata
@signature = signature
@policy = policy
end
def signature(options = {})
Base64.encode64(
OpenSSL::HMAC.digest(
OpenSSL::Digest::Digest.new('sha1'),
SECRET_ACCESS_KEY,
policy({ secret_access_key: SECRET_ACCESS_KEY })
)
).gsub(/\n/, '')
end
def policy(options = {})
Base64.encode64(
{
expiration: 30.minutes.from_now.utc.strftime('%Y-%m-%dT%H:%M:%S.000Z'),
conditions: [
{ bucket: MY_BUCKET },
{ acl: 'public-read' },
{ success_action_status: '201' },
["starts-with", "$key", "my_folder/"],
["content-length-range", 0, 2097152]
]
}.to_json
).gsub(/\n|\r/, '')
end The conditions inside policy can be modified to fit your requirements. They are outlined in the above Amazon article. Now in the javascript code (this upload gets triggered in summernote's onImageUpload callback) $(document).ready(function() {
$('.summernote').summernote({
height: 500,
onImageUpload: function(files, editor, welEditable) {
sendFile(files[0], editor, welEditable);
}
});
function sendFile(file, editor, welEditable) {
formData = new FormData();
formData.append('key', 'my_folder/' + file.name);
formData.append('AWSAccessKeyId', '<%= ACCESS_KEY %>');
formData.append('acl', 'public-read');
formData.append('policy', '<%= @policy %>');
formData.append('signature', '<%= @signature %>');
formData.append('success_action_status', '201');
formData.append('file', file);
$.ajax({
data: formData,
dataType: 'xml',
type: "POST",
cache: false,
contentType: false,
processData: false,
url: "https://<%= MY_BUCKET %>.s3-ap-southeast-2.amazonaws.com/",
success: function(data) {
// getting the url of the file from amazon and insert it into the editor
var url = $(data).find('Location').text();
editor.insertImage(welEditable, url);
}
});
}
}); And voila! p.s. note that its important to have the following in the ajax or jQuery is going to try and encode the request, resulting in a malformed POST error from Amazon. contentType: false,
processData: false, |
@pRdm Thank you for the in-depth response! It now works for me using Php. Here is what I use: <?php
$bucket = 'my_bucketname';
$folder = 'demo';
// these can be found on your Account page, under Security Credentials > Access Keys
$accessKeyId = 'replace with your access key id';
$secret = 'replace with your secret access key';
$policy = base64_encode(json_encode(array(
// ISO 8601 - date('c'); generates uncompatible date, so better do it manually
'expiration' => date('Y-m-d\TH:i:s.000\Z', strtotime('+2 days')),
'conditions' => array(
array('bucket' => $bucket),
array('acl' => 'public-read'),
array('success_action_status' => '201'),
array('starts-with', '$key', $folder.'/')
)
)));
$signature = base64_encode(hash_hmac('sha1', $policy, $secret, true));
?> And then my sendFile function with Php: function sendFile(file, editor, welEditable) {
formData = new FormData();
formData.append('key', '<?php echo $folder; ?>/' + file.name);
formData.append('AWSAccessKeyId', '<?php echo $accessKeyId; ?>');
formData.append('acl', 'public-read');
formData.append('policy', '<?php echo $policy; ?>');
formData.append('signature', '<?php echo $signature; ?>');
formData.append('success_action_status', '201');
formData.append('file', file);
$.ajax({
data: formData,
dataType: 'xml',
type: "POST",
cache: false,
contentType: false,
processData: false,
url: "https://<?php echo $bucket ?>.s3.amazonaws.com/",
success: function(data) {
// getting the url of the file from amazon and insert it into the editor
var url = $(data).find('Location').text();
editor.insertImage(welEditable, url);
}
});
} |
Hello all, someone please help. i don't know why image upload works in the github example page, but not in my local app. i'm just testing on the example page, is there some restriction I should be aware of? |
anyone who has .NET code for this (preferably VB)? I love summernote, but need to use s3 and .net, I have no idea of how Ruby works so struggling with converting. Thanks! :) |
C# example in this thread: |
This is my 2-cents for a php solution...
php file... saveimage.php
and that's it. Unless you want to move the image to a different directory, but that's for you to figure out.. :) |
Hey I'm not sure how you have things setup.. but when I replace your url: img_upload.php with my url:saveimage.php it works fine. I have posted my saveimage.php in the blog. Wayne. On Saturday, July 19, 2014 12:43:53 PM, suyudo notifications@github.com wrote: i get error like that.... how to solved it ? |
Is there an API call to add a class to the generated HTML IMG tag? Specifically, I would like the ability to add the bootstrap img-responsive class to any image uploaded via Summernote. I have thought about doing it when the the rich text is actually displayed on another page (not in the editor) - but that's not pretty. Another option is to modify the code within the editor during onblur or similar. |
I keep seeing https://github.com/HackerWins/summernote/blob/develop/dist/summernote.js#L3737
|
@pRdm Hello Patrick. I'm trying to follow some of these methods. I'm using Meteor. So I'm working with Javascript / Jquery, and your answer is the most closest I am getting. I am a completely new beginner and linking summer note to S3 has been a big difficult task for me. Could you kindly explain to me which parts I have to edit to my own settings from your example so I can study it and try to make it work? Thank you :) |
Спасибо авторам за Summernote, отличный редактор.
<textarea name="содержимое" id="содержимое"></textarea> `<script>
</script>`
[HttpPost] |
Thanks @alejandrosc. your script work for me. btw can you explain how to handle the process so that can't duplicate files on folder? |
Just to throw my Laravel (5.2) version into the mix. Using @Gorbulev-Sergey javascript with the addition of the Laravel csrf token.
The controller reached by posting to
If you want to avoid any duplicate files, you could skip the UUID bit and just rely on the original filename, but you may find you run into issues with overwriting files. |
Here's a workable MeteorJS version for you: On the client:
And on the server:
Where:
Hope this helps someone. It was a major pain in the ass getting this right. ;) |
Pictures uploaded in the tomcat8.5 JDK1.8 environment, upload pictures can not be displayed, you need to delay the implementation of the background JAVA upload code, 5 seconds to normal display Why does this problem arise? May I ask if you have similar problems? |
@crsssl & every
So everything is on client, except
|
Nice job @Ontokrat, and thanks for pointing out that package. It'll really help. |
Hi, how to upload image to server instead of base64 using asp.net webform? not the MVC. Im writing this javascript inside news_create.aspx. Then I define a function to upload the image in server. function sendFile(file,editor,welEditable) { |
I had the same problem as @piaoyizhimei and a few others... If you are updating the img src in the insertImage callback, you may need to trigger a change event manually after doing so:
|
if you using laravel 5.5 or higher, Try to using my code!
|
@Laeng i keep getting error 500, when trying to upload an image through summernote, could you post your php method to handle these DB uploads, please? I have figured out, you have the error on this line:
it should be just "r", why you have used "r.url" - i have no idea. |
@heihachi88 I using 'Xpresss Engine 3' and it's based laravel 5.5.
|
Can't i get ajax data with the following method:
It returns me nothing. |
@heihachi88 ajax post to server with query 'file' and server is most receive 'file'. larave 5.5 is not used at file upload to $requset->input('file');
|
I am using Laravel 5.6, but seems like ajax post not actually posting data to my controller.
Still returns nothing: "message": "Call to a member function getRealPath() on null" |
let's check debug!
Please put it before 'return'. if image is successful upload, |
Why you wrapped |
@heihachi88 it's my mistake.... haha! |
Here's response i get with
Something wrong with the ajax post. |
@heihachi88 Okay, image is not received to server. |
@heihachi88 |
I can confirm, that #72 (comment) works in Laravel 5.6 perfectly. In case someone stuck with it, just like a did, i'm posting my method for accepting post images:
|
THIS THE FKN SOLUTION |
the original solution for Rails is not working any more var sendFile = function(file, callback) {
var data;
data = new FormData();
data.append("file", file);
return $.ajax({
url: 'url_for_rails_to_handle_image_upload',
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data) {
return callback(data);
}
});
};
$(document).ready(function () {
$('.summernote').summernote({
callbacks: {
onImageUpload(files) {
sendFile(files[0], data => {
let imgNode = document.createElement("img");
imgNode.setAttribute('src', data.url)
$(this).summernote('insertNode', imgNode);
})
}
}
});
}); # rails side
def upload_editor_images
storage = Google::Cloud::Storage.new(
project_id: "project-id",
credentials: "path-to-credential-file"
)
bucket = storage.bucket "bucket-name"
image = bucket.create_file params[:file].tempfile.path, "/uploads/#{Rails.env}/by_editors/#{random = SecureRandom.hex}.jpg"
render json: { url: image.media_url }
end |
After some playing around with the codes provided in this issue I made an updated version compatible with Laravel 7.0. Feel free to use it. In web.php
App\Http\Controllers\Admon\SummernoteUploadController
The AJAX-function (can be placed in a global js-file or the file of the editor between script-tags
The callback included into the call to the form
Make sure you have your csrf token @csrf placed in de blade-file of the editor |
been working on this for days and I still don't know why it is not working for me. my form
my route
my initiate-summernote.js
|
Summernote converts uploaded image as a base64 data which is too large to store.
Is there way to inject amazon s3 service, so that only link gets stored in db?
The text was updated successfully, but these errors were encountered: