SummerNote onImageUpload converting server request to C# BASE64? - ajax

I have a C# MVC project where I will need to both use Summernote v0.8.2 as my WYSIWYG editor, along with exporting a PDF with jsPDF. I know that there are examples to make this work. My issue is that I need to custom resize/process the image that's inserted with summernote. Again, I know that you can capture this event using the onImageUpload callback. I'm having trouble correctly handing the incoming Request on the server to get the image and convert it into a BASE64 string. I would think this should be pretty easy, but I can't figure out what to do with the incoming Request to extract the Image. I've give you the whole process just to make sure you have enough info to help.
Here's my Summernote setup:
$('.summernote').summernote(
{
toolbar: [
['style', ['bold', 'italic', 'underline', 'clear']]
, ['fontname', ['fontname']]
, ['fontsize', ['fontsize']]
, ['color', ['color']]
, ['insert', ['picture']]
]
, callbacks: {
onImageUpload: function (image) {
uploadImage(image[0]);
}
}
}
);
Here's the AJAX call: FYI - I did change the data appended from image to file. Didn't change outcome.
function uploadImage(file, editor, welEditb) {
var data = new FormData();
//data.append("image", image);
data.append("file", file);
$.ajax({
url: '/home/UploadSummerNoteFile',
cache: false,
contentType: false,
processData: false,
data: data,
type: "post",
success: function (data) {
alert('display base64 data: ' + data);
//editor.insertImage(welEditable, url);
},
error: function (data) {
console.log(data);
}
});
}
My server method doesn't have any parameters, and I'm not sure how to extract just the FILE (IMAGE?) content. Once I get the actual file, I need to modify and change it (size, resolution, etc., which I can do), then convert it into BASE64 and send it back to the UI. So, my questions here this:
How do I get the file (image) from the request stream?
How do convert whatever this 'thing' is from above into BASE64?
I've used an online BASE64 converter for the image that I've been testing with so I know that my attempts haven't created a valid string.
Here's a partial example that I've found online, modified it (poorly) in an attempt to make work, which it doesn't:
byte[] buffer = new byte[Request.InputStream.Length];
Request.InputStream.Read(buffer, 0, buffer.Length);
string data = Encoding.Default.GetString(buffer);
string[] tokens = data.Split(',');
if (tokens.Length > 1)
{
// not sure what I'm doing, trying stuff. BOOOOM!
image = Convert.FromBase64String(tokens[1]);
base64 = Convert.ToBase64String(image);
//string fileName = DateTime.Now.ToString("yyyyMMddHHmmssffff") + ".png";
//string path = Path.Combine(#"D:\www\images", fileName);
//File.WriteAllBytes(path, image);
}
What do I need to do with the buffer or the data object? Where does the content of the file live in the request? Is it already converted when it was serialized for transport to the server? Also, assuming everything else gets completed, do I need to save the file to the server so it can be placed within Summernote's editor.insertImage(welEditable, url)? Thanks for your time and help!

Seems that I made this much harder than it needed to be. It's just a regular request, so extract the file from the request, and copy it to a memory stream. In this case I send back the BASE64 string to the calling function. Hopefully this helps others.
[HttpPost]
public JsonResult UploadFile()
{
var fileName = Request.Files[0].FileName;
var base64 = string.Empty;
using (var memoryStream = new MemoryStream())
{
Request.Files[0].InputStream.CopyTo(memoryStream);
var fileContent = memoryStream.ToArray();
base64 = Convert.ToBase64String(fileContent);
}
return Json(base64);
}
Here's the uploadImage ajax method changes: I create an instance of an IMG, and change the src to be the BASE64 value.
function uploadImage(file, editor, welEditb) {
var data = new FormData();
data.append("file", file);
$.ajax({
url: '/home/UploadSummerNoteFile',
cache: false,
contentType: false,
processData: false,
data: data,
type: "post",
success: function (data) {
var image = $('<img>').attr('src', 'data:' + file.type + ';base64,' + data);
$('.summernote').summernote("insertNode", image[0]);
},
error: function (data) {
console.log(data);
}
});
}

Related

How to PUT a binary file with javascript/jQuery to webdav?

How can I PUT a binary file, say an image with an HTTP PUT request to webdav? I already tried base64 encoding, but the file is broken.
$.ajax({
url: url + file,
data:base64content,
type: 'PUT',
crossDomain: true,
headers:{'content-type':'image/png'},
xhrFields:{withCredentials: true}
});
I've found a solution on this site:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data
var oReq = new XMLHttpRequest();
oReq.open("POST", url, true);
oReq.onload = function (oEvent) {
// Uploaded.
};
var blob = new Blob(['abc123'], {type: 'text/plain'});
oReq.send(blob);

Accept application/pdf in Ext.Ajax.request

I am using Ext.Ajax.request() to make an API call which produces MediaType.MULTIPART_FORM_DATA. This is being handled in the php layer which returns the object in
header("Content-Type: application/pdf");
echo $response;
The problem is, I am not able to handle the received object in the Ext.Ajax.request() since it always handles only Json objects by default.
I tried giving Headers, AcceptType in the request, but it always goes to the failure block.
Here is the code:
Ext.Ajax.useDefaultXhrHeader = false;
var responseText;
Ext.Ajax.request({
url: '/index.php/abc/xyz?value=' + value,
method: 'GET',
waitMsg: 'Printing Label',
contentType: 'application/octet-stream' //not sure,
responseType: 'blob' //not sure,
xhr2: false //not sure,
success: function (response) {
console.log("Success!!");
return "";
},
failure: function (response) {
//Always comes here. The API returns 200
console.log("Hi here in the error");
//Raw pdf gets printed
console.log(response.responseText);
}
});
but it always goes to the failure
For this you need to check in php side because may be something you have missed. I think may be this will help you readfile
Try with this code. Hope this will help/guide you to get required result.
Ext.Ajax.request({
url: '/index.php/abc/xyz?value=' + value,
method: 'GET',
waitMsg: 'Printing Label',
cors: true,
useDefaultXhrHeader: false,
withCredentials: true,
defaultHeaders: {
'Content-Type': 'application/octet-stream;'
},
timeout:0,//If don't know how time will take server to get the file then you can put 0. if you need
success: function(response) {
//In response you will directly get the octet-stream
//For showing pdf in front end side using blob url
var byteCharacters = atob(response.responseText),
len = byteCharacters.length,
byteNumbers = new Array(len),
key = 0,
byteArray,
blob,
contentType = 'application/pdf';
//insert charcter code in {byteNumbers}
for (; key < len; key++) {
byteNumbers[key] = byteCharacters.charCodeAt(key);
}
//convert {byteNumbers} into Uint8Array
byteArray = new Uint8Array(byteNumbers);
//create blob using {byteArray}
blob = new Blob([byteArray], {
type: contentType
});
// set {src} to {iframe}
window.open(window.URL.createObjectURL(blob), '_blank');
},
failure: function(response) {
//if somthing wrong in serverside then it will come in failure.
}
});
Hope this will also help you for this question as well.

Allow user to download a generated pdf file after uploading a file

I'm trying to allow a user to upload a 15 MB file to my web, from there that file should be posted to a web service of mine, receive the response (a pdf file) and serve that to the user so he can download it.
However, I'm ending in a URL like this with no prompt to download anything, just a 404 error: http://localhost:10080/Download?file=%PDF-1.4%%EF%BF%BD%EF%B (etc)
Some points:
First I will compress the file
Because of the previous point, I'm using Ajax to post the file
Ajax code
$("#file").on("change", function(evt) {
var files = evt.target.files;
/* Create zip file representation */
var zip = new JSZip();
/* Name, content */
zip.file("data.zip", files[0]);
zip.generateAsync({
compression: 'DEFLATE',
type: 'blob'
}).then(function(zc) { // Function called when the generation is complete
/* Create file object to upload */
var fileObj = new File([zc], "compressed-data");
/* form data oject */
var formData = new FormData();
/* $('#file')[0].files[0] */
formData.append('attachments', fileObj);
$.ajax({
type: "POST",
url: $("form#data").attr("action"),
data: formData,
contentType: false,
processData: false,
success: function (returnValue, textStatus, jqXHR ) {
window.location = '/Download?file=' + returnValue;
}
})
Python Web Code
def post(self):
attachments = self.request.POST.getall('attachments')
#handle the attachment
_attachments = [{'content': f.file.read(),
'filename': f.filename} for f in attachments]
# Use the App Engine Requests adapter. This makes sure that Requests uses
# URLFetch.
requests_toolbelt.adapters.appengine.monkeypatch()
#web service url
url = 'http://localhost:8080'
files = {'attachments': _attachments[0]["content"]}
resp = requests.post(url, files=files)
self.response.headers[b'Content-Type'] = b'application/pdf; charset=utf-8'
self.response.headers[b'Content-Disposition'] = b'attachment; filename=report.pdf'
self.response.out.write(resp.content)
Python Web Service Code
#app.route('/', methods=['POST'])
def hello():
#the attached ZIPPED raw data
f = request.files["attachments"]
#to unzip it
input_zip = ZipFile(f)
#unzip
data = [input_zip.read(name) for name in input_zip.namelist()]
generator = pdfGenerator(io.BytesIO(data[0]))
return generator.analyzeDocument()
The pdf generator uses Reportlab, writes the pdf over a
io.BytesIO() and returns it with output = self.buff.getvalue()
1.- What am I doing wrong with the window location thing?
2.- Am I doing something wrong with the file type?
I'm two days into this, now I need help.
Thanks.
However, I'm ending in a URL like this with no prompt to download anything, just a 404 error: http://localhost:10080/Download?file=%PDF-1.4%%EF%BF%BD%EF%B (etc)
That's what you're asking in window.location = '/Download?file=' + returnValue;, you redirect the user to /Download.
When you call your service, you should ask for a Blob response. Then, use saveAs (or FileSaver.js, a polyfill) to trigger the download.
As far as I know, $.ajax doesn't let you download binary content out of the box (it will try to decode your binary from UTF-8 and corrupt it). Either use a jQuery plugin (like jquery.binarytransport.js) or use a xhr directly.
$.ajax({
type: "POST",
url: $("form#data").attr("action"),
data: formData,
contentType: false,
processData: false,
dataType: 'binary', // using jquery.binarytransport.js
success: function (returnValue, textStatus, jqXHR ) {
// Default response type is blob
saveAs(returnValue, "result.pdf"); // using FileSaver.js
}
})

How do I handle image data returned from an ajax get request

I am trying to understand how to deal with the data returned from a Cross-Origin AJAX GET request. In this case it is supposed to return "an image". I am new to Ajax so I'm hoping there is a simple answer to this. I have to include the data = { width: 300px } in my GET request. Simply using the browser to display the image shows a 75px image. I am interacting with an API so this is the method they recommend to get a 300px version.
function Ajaxwrapper (MYurl, MYdata, errorHandler, callback, method) {
$.ajax({
url: MYurl,
data: MYdata,
type: method,
success: callback,
error: errorHandler,
xhrFields: { withCredentials: true }
});
}
function getPreview (el) {
var url = 'http://MYURL';
var data = {
book: {
width: '300px'
}
};
Ajaxwrapper(url, data, function(xhr){ console.log(xhr.status); }, function(data){
// How the heck do I deal with the data
var HTMLpreview = '<img src="' + data + '">';
el.append(HTMLpreview);
}, 'get');
}
THIS IS WHAT IS OUTPUTTED USING THE IMG SRC="returned data":
+���+�\�E��{�%�ns�$��E�9�k;k�-� �fd��Y�}��e�K���w��f#X���"Q�G%�ͼ%�����D5����"��2�!'��tbF����[����A0���5�>����' +���������-9���|8e� $0�GD�ڃ�e"t:C�<�������?�Z� �=��>��?�Oo����}�����6�o����}����b�zMuUťR��ds`� ֞�z�J���s~?{w��9�ֳ��bܠ"g����ط(�ٙ���dv��:���c���ʮd��Y�}��h��X���r��4 ]5���r��,d�"=��$�q����e���e�I|:<*DP]K`.��M�s�p��G�"���V]��F�ãѠQ ���(P�� :�"" )+%�ߏ���b�T���o��n�1>s��v�l[�L������{32]X��۾�T�\�{�_9U̗V+#���-8+�
Any help would really be appreciated.
-David
Your question is a little confusing so this may not be what you're looking for.
Your api should give you information on what type of data it is returning (content type). You can use that to decide what to do with the result.
It looks like you're getting a binary image file. You can create a dom image object and insert it into your page to be displayed
If you're using straight javascript without a wrapper library it may be something like this: http://xhr.spec.whatwg.org/

RecorderJS uploading recorded blob via AJAX

I'm using Matt Diamond's recorder.js to navigate the HTML5 audio API, and feel this question probably has an apparent answer, but i'm unable to find any specific documentation.
Question: After recording a wav file, how can I send that wav to the server via ajax? Any suggestions???
If you have the blob you'll need to turn it into a url and run the url through an ajax call.
// might be nice to set up a boolean somewhere if you have a handler object
object = new Object();
object.sendToServer = true;
// You can create a callback and set it in the config object.
var config = {
callback : myCallback
}
// in the callback, send the blob to the server if you set the property to true
function myCallback(blob){
if( object.sendToServer ){
// create an object url
// Matt actually uses this line when he creates Recorder.forceDownload()
var url = (window.URL || window.webkitURL).createObjectURL(blob);
// create a new request and send it via the objectUrl
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "blob";
request.onload = function(){
// send the blob somewhere else or handle it here
// use request.response
}
request.send();
}
}
// very important! run the following exportWAV method to trigger the callback
rec.exportWAV();
Let me know if this works.. haven't tested it but it should work. Cheers!
#jeff Skee's answer really helped but I couldn't grasps it at first, so i made something simpler with this little javascript function.
Function parameters
#blob : Blob file to send to server
#url : server side code url e.g. upload.php
#name : File index to reference at the server side file array
jQuery ajax function
function sendToServer(blob,url,name='audio'){
var formData = new FormData();
formData.append(name,blob);
$.ajax({
url:url,
type:'post',
data: formData,
contentType:false,
processData:false,
cache:false,
success: function(data){
console.log(data);
}
}); }
Server side code (upload.php)
$input = $_FILES['audio']['tmp_name'];
$output = time().'.wav';
if(move_uploaded_file($input, $output))
exit('Audio file Uploaded');
/*Display the file array if upload failed*/
exit(print_r($_FILES));
I also spent many hours trying to achieve what you are trying to do here. I was able to successfully upload the audio blob data only after implementing a FileReader and calling readAsDataURL() to convert the blob to a data: URL representing the file's data (check out MDN FileReader). Also you must POST, not GET the FormData. Here's a scoped snippet of my working code. Enjoy!
function uploadAudioFromBlob(assetID, blob)
{
var reader = new FileReader();
// this is triggered once the blob is read and readAsDataURL returns
reader.onload = function (event)
{
var formData = new FormData();
formData.append('assetID', assetID);
formData.append('audio', event.target.result);
$.ajax({
type: 'POST'
, url: 'MyMvcController/MyUploadAudioMethod'
, data: formData
, processData: false
, contentType: false
, dataType: 'json'
, cache: false
, success: function (json)
{
if (json.Success)
{
// do successful audio upload stuff
}
else
{
// handle audio upload failure reported
// back from server (I have a json.Error.Msg)
}
}
, error: function (jqXHR, textStatus, errorThrown)
{
alert('Error! '+ textStatus + ' - ' + errorThrown + '\n\n' + jqXHR.responseText);
// handle audio upload failure
}
});
}
reader.readAsDataURL(blob);
}
Both solutions above use jQuery and $.ajax()
Here's a native XMLHttpRequest solution. Just run this code wherever you have access to the blob element:
var xhr=new XMLHttpRequest();
xhr.onload=function(e) {
if(this.readyState === 4) {
console.log("Server returned: ",e.target.responseText);
}
};
var fd=new FormData();
fd.append("audio_data",blob, "filename");
xhr.open("POST","upload.php",true);
xhr.send(fd);
Server-side, upload.php is as simple as:
$input = $_FILES['audio_data']['tmp_name']; //temporary name that PHP gave to the uploaded file
$output = $_FILES['audio_data']['name'].".wav"; //letting the client control the filename is a rather bad idea
//move the file from temp name to local folder using $output name
move_uploaded_file($input, $output)
source | live demo

Resources