Cloudinary jQuery Direct Upload issue - cloudinary

I am implementing Cloudinary Jquery Upload. From my file upload webpage, if I surf to another website ( google.com, or any external website), and then click on the back button on the browser into this same file upload page, the upload fails.
The error message I gotten back is (from Firebug):
400 Bad Request
{"error":{"message":"Upload preset Must specify upload preset when using unsigned upload”}}
I did not enable unsigned upload on the Cloudinary management console
because my intention is a signed upload
This is the JSON data that is created at the backend for data-form-data:
{"timestamp":1409146953,"callback":"http://newappsure.herokuapp.com/vendor/cloudinary/cloudinary_cors.html","signature":"19071a3e822eed51238454e359589f52cccca042","api_key":"224456847515364”}
Below is the javascript and input HTML:
<script type="text/javascript”>
$.cloudinary.config({cloud_name:'dashy', api_key:’XXXXXXXXXXXXXXX'});
</script>
<input name="file" type="file" id="uploadinput" class="cloudinary-fileupload" data-cloudinary-field="image_upload"
data-form-data="" ></input>
<script>
$.ajax({
url: '/filer',
type: 'POST',
success: function(response){
$('#uploadinput').attr('data-form-data', response);
}
});
</script>
This is the Ruby backend that generates JSON:
post '/filer' do
ts = Time.now.getutc.to_time.to_i.to_s
secret="XXXXXXXXXXXXXXXXXXXXXX"
altogether="callback=http://newappsure.herokuapp.com/vendor/cloudinary/cloudinary_cors.html&timestamp="+ts+secret
sig=Digest::SHA1.hexdigest altogether
ts = Time.now.getutc.to_time.to_i
{:timestamp => ts, :callback => "http://newappsure.herokuapp.com/vendor/cloudinary/cloudinary_cors.html", :signature => sig, :api_key =>"XXXXXXXXXXXXXXXX"}.to_json
end
Please help me understand what did I do wrong?

While your solution may work, the more optimal way is to update the upload parameters to call $(...).fileupload({formData: data}) where data is the parameters hash (not JSON serialized).
For more information:
http://support.cloudinary.com/entries/24950218-Why-is-updating-a-cloudinary-fileupload-field-dynamically-not-working-

Got it working by forcing the page to reload with the following snippets (ref: https://stackoverflow.com/a/9217531/3781343 and http://www.webdeveloper.com/forum/showthread.php?137518-How-to-refresh-page-after-clicking-quot-Back-quot-button)
<input type="hidden" id="refreshed" value="no">
<script type="text/javascript">
onload=function(){
var e=document.getElementById("refreshed");
if(e.value=="no")e.value="yes";
else{e.value="no";location.reload();}
}
</script>

Related

sending POST request to express route - after receiving form data, res.render is not triggered

I'm trying to create a simple app where a picture gets uploaded, and that picture is drawn on html canvas so that i can do some simple pixel manipulation.
Right now I have the GET method for root render an EJS template with a fileReader and a canvas.
With code attached at the bottom of the EJS file through script tags, I draw the uploaded image onto the canvas so I can read each pixel's rgb values.
I then tried to send those rgb values to the POST route in the app (through fetch), but it's not working as expected.
app.post("/", (req, res)=>{
console.log("inside post");
console.log(req.body);
res.render("test", {result: req.body});
console.log("after res.render");
});
All three of the console logs print correctly in the terminal, including the request body, but the test template is not being rendered. It just stays on the same "index" view the app launches with.
Can someone give me some insight as to why this is happening? I also included console logs inside the script tags in the ejs template, and these are only displayed in the browser, not in the terminal I launch the express app with. How can I render the view inside the post method?
First
If you use AJAX like Fetch API or XHR, browser will not render the test page.
Because it's asynchronous, and you could see Ajax in MDN web docs.
You need to use form post with following code.
<form action="/" method="post">
<button type="submit">go to another page</button>
</form>
But, if you use form post, your page which might be "index.ejs" will be replaced with "test.ejs".
In other words,
Browser uses the response from the forms POST request to load the new page.
But browser pass AJAX request's response to a callback and trigger callback in js.
Browser handle these two type request (Form Post and AJAX POST) with different ways.
In common, both are sending data to server.
So, in your case, res.render is triggered successfully.
Let me show you an example. Here is my server code.
const express = require('express')
const app = express()
app.set("view engine", "ejs")
app.get("/", (req, res, next) => {
res.render("test")
})
app.post("/test", (req, res, next) => {
res.render("other-test")
})
app.listen(3000)
<!-- test.ejs -->
<h1>this is test pages.</h1>
<!-- other-test.ejs -->
<h1>this is other test pages.</h1>
When I type url http://localhost:300, browser show me this.
And I open console in chrome and type following code.
fetch("/test", {
method: 'POST', // or 'PUT'
body: JSON.stringify({}), // data can be `string` or {object}!
}).then(res => {console.log("trigger response")})
Then go the network tab in chrome, you will see the request.
Here, this request trigger the express method.
But, what is the response?
Well, it's a html. That means res.render("other-test") is triggered correctly.
And you will find the console output show "trigger response" which callback is triggered in my fetch.
And, page still stay in "test.ejs".
Next, I add following code in my test.ejs
<form action="/test" method="post">
<button type="submit">Go to other page</button>
</form>
Page will be like this.
After you click, you will find out the browser show you "other-test" content.
That's a difference between form post and ajax post.
Second
You put script tag into ejs template.
Express will use ejs engine to render your ejs template become to html page.
After it become to html page, it means all script is running in browser not your nodejs terminal.

IE 11 (or 10) kendo ui file upload will not upload unless I refresh the page (ctrl-F5)

Environment specifics:
MVC4 app
Kendo UI File Upload
IE 11 (or 10)
Windows Authentication
When I load the view for the application that has the file upload kendo tool in IE the file upload returns a 401 unauthorized error (traced from server). If I refresh the page (ctrl-F5) then the tool works fine. This tool works fine with Chrome.
any idea why or how to fix?
you will not believe the insanity I had to go through to get a solution to this:
I dropped a document ready jquery snippit at the end of the document to force it to authenticate an action on my controller.
<div id="checkauth" style="display: none;"></div>
<script type="text/javascript">
$(function () {
$.ajax({
url: '\AcceptanceFileValidator\CheckAuth'
}).done(function (d) {
$('#checkauth').html(d.uid)
});
});
</script>
and on the controller:
public JsonResult CheckAuth()
{
return Json(new { uid = Guid.NewGuid().ToString() }, JsonRequestBehavior.AllowGet);
}

how to pass file from client to controller by jquery?

i want to create very simple sample to uploading a file by client side in mvc4 by jquery and java script.
i Google it and found many samples and many plugins on internet but i prefer to do not have any dependency on any extra plugin or library like "uploadify"
for this i create a simple mvc4 application and in my view i attach my script file that contains method bellow until user click a button on this view start to uploading.
i do not know how to change bellow method to pass file to controller(in client side) ?
function uploadimage() {
$.ajax({
url: "/Uploader/FileUpload",
type: 'POST',
dataType: 'json',
data:null,
contentType: 'application/json; charset=utf-8',
success: function (msg) {
},
error: function (xhr) {
}
});
}
in my view
<input type="file" id="fileToUpload" name="file" />
<input type="button" value ="Upload" onclick="uploadimage()"/>
my controller
public ActionResult FileUpload(HttpPostedFileBase file)
{
//do somethings with file
}
file upload is not possible through ajax. You can upload file, without refreshing page by using IFrame.

filepicker urls with s3

I'm looking to build a photo management app and I've decided to use Filepicker.io with Amazon s3 to manage the uploads/hosting of static files. I plan on having Filepicker handle the upload of images to s3, and then I will store the url of the image in a database -- these urls will be embedded in a template. For example,
HTML:
<input type="file" name="datafile">
{{#if src}}
<img src='{{src}}'>
{{/if}}
Javascript :
'change input' : function (e, t) {
var file = e.currentTarget.files[0];
if (file) {
filepicker.store(file, function(fp){
// Set URL to fpURL
}, function(err){
console.log('error', err);
}, function(progress){
console.log('loading', progress);
});
}
}
My question: Is it better to store the filepicker url in the database? Or should I be saving the key url, which can link directly to s3?
My filePicker success object looks like this:
{url: "https://www.filepicker.io/api/file/wppeyWAUQaaX0HPgXQ",
size: 76511, type: "image/png",
key: "EdqmSpbDQziIvSfI4g_logo.png",
filename: "logo.png"}
We recommend storing the URL directly, as that way you can take advantage of the conversion features and other functionality we provide on top of the URLs. Plus, you don't have to mess with the S3 APIs directly and can perform GETs and POSTs on the url instead

Loading audio via a Blob URL fails in Safari

Following code works in Chrome (22.0) but not in Safari (6.0)
<!DOCTYPE html>
<html>
<head>
<script>
function onGo(e) {
var fr = new FileReader();
var file = document.getElementById("file").files[0];
fr.onload = function(e) {
var data = new Uint8Array(e.target.result);
var blob = new Blob([data], {type: 'audio/mpeg'});
var audio = document.createElement('audio');
audio.addEventListener('loadeddata', function(e) {
audio.play();
}, false);
audio.addEventListener('error', function(e) {
console.log('error!', e);
}, false);
audio.src = webkitURL.createObjectURL(blob);
};
fr.readAsArrayBuffer(file);
}
</script>
</head>
<body>
<input type="file" id="file" name="file" />
<input type="submit" id="go" onclick="onGo()" value="Go" />
</body>
</html>
In Safari, neither callback (loadeddata nor error) is called.
The content used is an mp3 file, which is normally played back with audio tag.
Is there any special care needed for Safari?
Many years later, I believe the example in the OP should work just fine. As long as you somehow set the mime type when creating the blob, like the OP does above with the type property of the options passed in:
new Blob([data], {type: 'audio/mpeg'});
You could also use a <source> element inside of an audio element and set the type attribute of the <source> element. I have an example of this here:
https://lastmjs.github.io/safari-object-url-test
And here is the code:
const response = await window.fetch('https://upload.wikimedia.org/wikipedia/commons/transcoded/a/ab/Alexander_Graham_Bell%27s_Voice.ogg/Alexander_Graham_Bell%27s_Voice.ogg.mp3');
const audioArrayBuffer = await response.arrayBuffer();
const audioBlob = new Blob([audioArrayBuffer]);
const audioObjectURL = window.URL.createObjectURL(audioBlob);
const audioElement = document.createElement('audio');
audioElement.setAttribute('controls', true);
document.body.appendChild(audioElement);
const sourceElement = document.createElement('source');
audioElement.appendChild(sourceElement);
sourceElement.src = audioObjectURL;
sourceElement.type = 'audio/mp3';
I prefer just setting the mime type of the blob when creating it. The <source> element src attribute/property cannot be updated dynamically.
I have the same problem, and I spend a couple days troubleshooting this already.
As pwray mentioned in this other post, Safari requires file extensions for media requests:
HTML5 Audio files fail to load in Safari
I tried to save my blob to a file, named it file.mp3 and Safari was able to load the audio that way, but after I renamed the file to have no extension (just "file"), it didn't load.
When I tried the url created from the blob in another tab in Safari:
url = webkitURL.createObjectURL(blob);
it download a file right away called "unknown", but when I tried the same thing in Chrome (also on Mac), it showed the content of the file in the browser (mp3 files start with ID3, then a bunch of non-readable characters).
I couldn't figure out yet how I could force the url made of blob to have an extension, because usually it looks like this:
blob:https://example.com/a7e38943-559c-43ea-b6dd-6820b70ca1e2
so the end of it looks like a session variable.
This is where I got stuck and I would really like to see a solution from some smart people here.
Thanks,
Steven
Sometimes, HTML5 audio can just stop loading without any apparent reason.
If you take a look to the Media Events (http://www.w3schools.com/tags/ref_eventattributes.asp) you´ll see an event called: "onStalled", the definition is "Script to be run when the browser is unable to fetch the media data for whatever reason" and it seems that it should be helpful for you.
Try listening for that event and reloading the file if necessary, with something like this:
audio.addEventListener('onstalled', function(e) {
audio.load();
}, false);
I hope it helps!
Just use source tag in audio.
<audio controls>
<source src="blob" type="blobType">
</audio>