I am building a chrome-extension that is required to upload a CSV file to dropbox.
Everything works fine apart of the way the data is structured inside the file that has been successfully uploaded to dropbox.
I am also downloading a local copy of the file and everything looks fine for it, but on dropbox it doesn't seem to recognize the endline characters ("/r/n"), and it translates the white spaces as "%20". Here is a part of my code where I create the file and upload it to dropbox:
function downloadCSV()
{
localStorage["timeStamp"]="inactive";
localStorage["ProfileViews"]="";
// create a csv file with the table data using base64
var encodedUri = encodeURI(localStorage.Table);
var file = 'data:Application/octet-stream,' + encodedUri;
var date = new Date();
// filename contains the unique user id + a timestamp of the current date with year, month, day, hours, minutes, seconds
var filename=uniqueID +" "+date.getYear()+ "-" +date.getMonth() +"-" +date.getDate() +": " +date.getHours() + "." +date.getMinutes() +": "+date.getSeconds()+".csv";
var link = document.createElement("a");
link.setAttribute("href", file);
link.setAttribute("download", filename);
link.click();
//create a xmlhttp request to send a post request to box.com using the authenthification token
var uploadUrl = 'https://api-content.dropbox.com/1/files_put/dropbox/myfolder/'+filename;
// The Box OAuth 2 Header. Add your access token.
var headers = {
Authorization: 'Bearer '+localStorage.authorization_token
};
$.ajax({
url: uploadUrl,
headers: headers,
type: 'PUT',
// This prevents JQuery from trying to append the form as a querystring
processData: false,
contentType: false,
data: link
}).complete(function ( data ) {
// Log the JSON response to prove this worked
console.log(data.responseText);
});
// resets the Table variable
localStorage["Table"]="";
}
I tried to encoded in every possible way but the result is still the same. Any assistance in solving this would be much appreciated.
I don't understand what you're trying to do in your code. It looks like you're creating a hyperlink with a URL-encoded version of your data as the href, but then you're passing that link variable as the data to an AJAX request... what does that end up doing? You should just pass the data:
$.ajax({
...
data: /* the actual data you want to upload here */
...
});
I can't tell from your code if localStorage.Table is the actual CSV data or not. (A comment mentions base64 encoding?) But whatever variable holds the exact CSV data you want in the file should be passed as the data parameter on your HTTP request. Don't base64-encode, don't URL encode, etc.
Try using contentType:'application/octet-stream'
Related
I'm trying to upload a video file in chunks to a server via a standard jQuery $.ajax call. The process is simple:
Use the slice() method on the file object to read a chunk
Use FileReader.readAsArrayBuffer to read the resulting blob
Create a Uint8Array of that result in the FileReader.onload callback
Use String.fromCharCode.apply(null, intArrayName) to convert it into a binary string
Upload that binary string as a chunk in the AJAX call's data property
When I finish uploading all the chunks, the server's API complains that the file upload is incomplete. To test this method, I converted the concatenated binary strings into a Blob and had Chrome save it to my downloads folder, only to find out my media player said the file was unplayable.
I've read posts on this site and other articles suggesting that directly converting binary data represented by integers to strings results in a loss of data, and that the suggestion is convert it to a base64-encoded string, since Javascript doesn't have a StreamContent object like C# does.
The problem is that even if I set Content-Transfer-Encoding to base64 I don't think the API (which wasn't written by us) picks up on it and can tell that a base64 decoding is needed.
My question is: is this the only sure-fire way of sending video data over an AJAX call safely? If not, how else can I send it in the data field of my AJAX request? There are probably thousands of uploaders like this on the Internet but nowhere can I find solid documentation on how to do this. If it turns out that the server needs to expect base64 encoding, we might have to write a middle-man API to do this decoding for us.
Thanks to Patrick Evans, it turns out all I needed to do was upload the blob itself:
function upload(file) {
var offset = 0; // what's been sent already
var fileSize = file.size;
var chunkSize = 64 * 1024; // bytes
while (offset < fileSize) {
var blob = file.slice(offset, chunkSize + offset);
var urlToUse = ((offset + blob.size) >= fileSize) ? videoFinishBaseUrl : videoContinueBaseUrl;
$.ajax({
url: urlToUse,
method: 'POST',
data: blob,
headers: requestHeaders,
contentType: false,
processData: false,
cache: false,
async: false,
success: function(data) {
jQuery('#uploadmsg').text('Finished offset ' + offset);
offset += blob.size;
},
error: function(err) {
jQuery('#uploadmsg').text(err);
}
});
}
};
I have the following data both in my js file or as a param in rails. Togther there is an image that is to be sent to server, what I want to achieve is to crop the image based on the data such as below. I am not allowed to use gems :) just using ruby/js code if I can manipulate the image already in js side. I am using cropper js which generated the output to me. What should I do to achieve cropping ?
{"x":552.697358490566,"y":-72.49509433962258,"width":696.9599999999999,"height":696.9599999999999,"rotate":0,"scaleX":1,"scaleY":1}
Check out the fiddle: Link
This is the code you should be using, since your JSON is already formatted the same way Cropper takes its input:
//get the data from your rails framework and save it in a variable, below I just pasted the same data you put in your question
var data = {"x":552.697358490566,"y":-72.49509433962258,"width":696.9599999999999,"height":696.9599999999999,"rotate":0,"scaleX":1,"scaleY":1};
//remember to change my-picture to the id of your img
$('#my-picture').cropper('setData', data);
//also make sure to bind this to your own button
$('#crop-button').click(function(e){
//this will transform the image into a blob, so you can submit it in form data
$(this).href = $('#my-picture').cropper("getCroppedCanvas").toBlob(function (blob) {
var formData = new FormData();
formData.append('croppedImage', blob);
//this is where you put your Rails path to upload
//it's going to be a POST, so you should know how to handle it
$.ajax('/path/to/upload', {
method: "POST",
data: formData,
processData: false,
contentType: false,
success: function () {
console.log('Upload success');
},
error: function () {
console.log('Upload error');
}
});
});
});
I really have no prior knowledge to Blob objects in JavaScript aside from what I've read here but need to use them to convert a string of binary data into a .xls file which I then make available to the user. The catch is when I construct a blob, get the location, and open up the file to look at it, it opens up saying
The file you are trying to open is in a different format that
specified by the file extension. Verify that the file is not
corrupted and is from a trusted source before opening the file.
(I know this data is incorrect because when I submit the form normally I get the file correctly and don't have this issue)
This is done in an ajax call and the success functions parameter data is the binary data.
$("#fileForm").submit(function(){
var fileData = $("#fileInputElmt").prop("files")[0];
var data = new FormData();
data.append("upload",fileData);
var url = "process.action?" + $("#fileForm").serialize();
$.ajax({
type: "POST",
url:url,
data:data,
cache:false,
contentType:false,
processData:false,
success:function(data){
var bb = new Blob([data],
{ type: 'application/vnd.ms-excel',endings:'native'});
var bUrl = URL.createObjectURL(bb);
window.open(bUrl,"_self");
hideProgressBar();
},error:function(data){
hideProgressBar();
}
});
return false;
});
Am I doing something wrong? or is there a better way of doing this?
My application asks from the user to capture an photo and then upload it to the server if the user is online. The code for the photo capture I took from PhoneGap API. How can I use the imgURL to upload it to the REST interface using Json and Jquery mobile?
The code I have up to now is:
function onPhotoDataSuccess(imageData) {
// Uncomment to view the base64 encoded image data
// console.log(imageData);
// Get image handle
//
var smallImage = document.getElementById('smallImage');
// Unhide image elements
//
smallImage.style.display = 'block';
// Show the captured photo
// The inline CSS rules are used to resize the image
//
smallImage.src = "data:image/jpeg;base64," + imageData;
}
Again, it is the same code taken from the PhoeGap API... I appreciate any help!...
Not sure if I understand your question correctly.
You should have your rest url and data structure (in JSON) the endpoint expects.
Once you have the base64 encoded string Use JSON library for packing JSON data and then send it to the service using
jquery.ajax().
Edited to include the post code
$.ajax({
type: 'POST',
url: yoururl,
data: jsondata,
success: success,
dataType: dataType
});
Content type will usually be
contentType: "application/json; charset=utf-8"
and datatype will be
dataType: 'json'
I am using Open Flash Chart 2 to create some graphs. I want to be able to save an image of the graph, which OFC2 supplies some methods to accomplish this. I used the example on the OFC2 site to directly display the raw image data on the page, but that does not work in IE6, which most of our users are using (I know, I know).
I switched to using the OFC2 method, post_image to post the raw image data to the server. I use a Perl script to receive the image data, save it to a file, and I can view the image. The unfortunate part about using the post_image method is that ActionScript throws an error when saving the image:
Error #2101: The String passed to URLVariables.decode() must be a URL-encoded query string containing name/value pairs.
Which apparently is a bug in Adobe - see this page. Because of this error, the post_image method does not complete successfully, so the javascript callback won't ever fire - I basically don't have a way to tell if the image was saved successfully.
So, I thought I would use the get_img_binary method of OFC2 to get the binary data of the image, and use jQuery to post the binary data to my Perl script.
I cannot figure out how to send the binary data correctly, or how to let my Perl script receive the binary data correctly, or both.
Here is my jQuery function:
var chartObj = $("#chart_object").get(0);
$.ajax({
type: "POST",
url: 'download_image.pl',
//contentType: 'application/octet-stream',
contentType: 'image/png',
//processData: false,
//data: { imgData: chartObj.get_img_binary() },
data: chartObj.get_img_binary(),
dataType: "text",
success: function(data) {
console.log( data );
}
});
You can see from some of my commented out lines that I have tried various contentTypes and other settings of the Ajax call.
The Ajax call is sending some data, but it doesn't appear to be binary. I think it is a base64 representation of the binary data.
Does anyone have any ideas on how to send binary data from javascript to the server?
The Perl script I have works fine for the post_image method, so I don't think the problem is there?
Thanks in advance!
I seem to have stumbled onto the solution.
Here is my ajax call:
var chartObj = $("#chart_object").get(0);
$.ajax({
type: "POST",
url: 'download_image.pl',
contentType: 'application/octet-stream',
processData: false,
data: imgData,
dataType: "text",
success: function(data) {
console.log( data );
}
});
And here is my Perl snippet to process/save the image:
use CGI qw(:standard);
use MIME::Base64;
...
my $img64 = param('POSTDATA');
my $img = decode_base64( $img64 );
...
#then print $img out to a file in binary mode
I had to decode the base64 representation of the PNG file, and then save it to a file.
i've got trouble too with using IE6 and OFC2 for saving image... So here are the scripts i use (javascript + PHP)
i know it's not very beautifull but jQuery doesn't want to work in a popup created via window.open('') on my IE6 so i decided to use a "old school method" to get it...
// javascript in the page displaying the flash chart
OFC = {};
OFC.jquery = {
name: "jQuery",
image: function(src) { return '<img src="data:image/png;base64,' + $('#'+src)[0].get_img_binary() + '" \/>'},
popup: function(src) {
var img_tag = OFC.jquery.image(src);
var img_win = window.open('', 'imagesave');
img_win.document.write('<html><head><title>imagesave<\/title><\/head><body>'+ img_tag + '<\/body><\/html>');
img_win.document.close();
},
popupie: function(src) {
var img_data = "image/png;base64,"+$("#"+src)[0].get_img_binary();
var img_win = window.open('', 'imagesave');
with(img_win.document) {
write('<html>');
write('<head>');
write('<title>imagesave<\/title>');
write('<\/head>');
write('<body onload="document.forms[0].submit()">');
write('<form action="\/ofc\/base64post.php" method="post">');
write('<input type="hidden" name="d" id="data" value="'+img_data+'" \/>');
write('<\/form>');
write('<div><img src="\/ofc\/ajax-loader.gif" border="0" alt="" \/><\/div>');
write('<div style="font-family: Verdana;">Please wait<br \/>After you can save the image<\/div>');
write('<\/body>');
write('<\/html>');
}
img_win.document.close();
}
}
function save_image() { // this function is automatically called
if ($.browser.msie)
OFC.jquery.popupie("my_chart"); // only for IE navigators
else
OFC.jquery.popup("my_chart"); // for the others
}
so, when we use the save_image() function (which is automaticaly called when you right clic dans select "Save Image Locally" on the flahs chart)
the image of the chart is tranfered to the popup and the data (base64 binary image) are posted to a php script /ofc/base64post.php that rander the picture :
<?php
// base64post.php
$data = split(';', $_POST['d']);
$type = $data[0];
$data64 = split(',', $data[1]);
$pic = base64_decode($data64[1]);
header("Content-type: $type");
echo $pic;
?>
hope that help someone !