Using Dropbox v2 API from Browser - javascript

I'm trying to upload data to dropbox via webbrowser (FF 42.0, PhantomJS 1.9.8) and dropbox v2 api. My function looks like this
function(path, data, callback) {
$.ajax({
url: 'https://content.dropboxapi.com/2/files/upload',
type: 'post',
contentType: 'application/octet-stream',
beforeSend: function(jqXHR) {
jqXHR.setRequestHeader("Content-Type","application/octet-stream");
},
data: data,
headers: {
"Authorization": "Bearer " + token,
"Dropbox-API-Arg": '{"path": "' + path + ',"mode": "add","autorename": true,"mute": false}',
"Content-Type": "application/octet-stream"
},
success: function (data) {
callback(data);
}
});
}
Even I set the Content-Type at all attributes I can think of to application/octet-stream I get the following error
Error in call to API function "files/upload": Bad HTTP "Content-Type" header: "application/octet-stream
; charset=UTF-8". Expecting one of "application/octet-stream", "text/plain; charset=dropbox-cors-hack"
Taking a look at the request in Firebug shows me that the Content-Type was really set to application/octet-stream; charset=UTF-8. When trying text/plain; charset=dropbox-cors-hack as Content-Type the sent request has text/plain; charset=UTF-8, and I get the same error message.
How can I make jquery and my browser to set the headers I need.
EDIT: Same behavior in Chrome
IE works as expected

Technically, Firefox is just adhering to the W3C XMLHttpRequest spec:
http://www.w3.org/TR/XMLHttpRequest/#the-send()-method
Sending anything other than a Blob or ArrayBufferView can cause issues with browsers attempting to encode the data in UTF-8 (to follow the spec).
The right thing to do here is to avoid sending data as a String. Here are two examples of how to avoid this behavior:
// ... file selected from a file <input>
file = event.target.files[0];
$.ajax({
url: 'https://content.dropboxapi.com/2/files/upload',
type: 'post',
data: file,
processData: false,
contentType: 'application/octet-stream',
headers: {
"Authorization": "Bearer " + ACCESS_TOKEN,
"Dropbox-API-Arg": '{"path": "/test_ff_upload.txt","mode": "add","autorename": true,"mute": false}'
},
success: function (data) {
console.log(data);
}
})
Or, if you want to send up text, you can UTF-8 encode the text before uploading yourself. A modern way to do this is using TextEncoder:
var data = new TextEncoder("utf-8").encode("Test");
$.ajax({
url: 'https://content.dropboxapi.com/2/files/upload',
type: 'post',
data: data,
processData: false,
contentType: 'application/octet-stream',
headers: {
"Authorization": "Bearer " + ACCESS_TOKEN,
"Dropbox-API-Arg": '{"path": "/test_ff_upload.txt","mode": "add","autorename": true,"mute": false}'
},
success: function (data) {
console.log(data);
}
})

Try this...
private void upload(object sender, EventArgs e)
{
OAuthUtility.PutAsync
(
"https://content.dropboxapi.com/1/files_put/auto/",
new HttpParameterCollection
{
{"access_token",Properties.Settings.Default.AccessToken},
{ "path", Path.Combine(this.CurrentPath, Path.GetFileName(openFileDialog1.FileName)).Replace("\\", "/") },
{ "overwrite","false"},
{ "autorename","false"},
{openFileDialog1.OpenFile()}
},
callback : Upload_Result
);
}

Related

How to get oauth access_token with jQuery (localhost)?

I am trying to get access_token utilizing jQuery. Problem is, that I cannot get that token (server is running on localhost). Server works fine (I tried that with postman), but I cannot get it with jQuery.
Browser writes after clicking on the button.
The resource from “http://localhost:8080/oauth/token?callback=jQuery34105901959820360243_1562175129954&grant_type=password&client_id=my-client&client_secret=my-secret&username=test%40seznam.cz&password=Peter&_=1562175129955” was blocked due to MIME type (“application/json”) mismatch (X-Content-Type-Options: nosniff).
jQuery function to get access_token
function authenticateUser(email, password) {
var body = {
grant_type: 'password',
client_id: 'my-client',
client_secret: 'my-secret',
username: "test#seznam.cz",
password: "Peter"
};
$.ajax({
url: 'http://localhost:8080/oauth/token',
crossDomain: true,
type: 'POST',
dataType: 'jsonp',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
header: {"Access-Control-Allow-Origin": "*"},
data: body,
complete: function(result) {
alert(result);
},
success: function(result) {
alert(result + " OK!");
},
error: function(result) {
alert(result + " CHYBA");
},
});
return true;
}
If the javascript file is served by the same server that gives out the tokens then there's no need to use the full url in your jquery ajax code (and there's no need to indicate crossDomain=true). It also seems that your server is expecting json content type instead of url-encoded
use
url: '/oauth/token',
crossDomain: false,
...
contentType: 'application/json; charset=UTF-8',
To make the request
Edit
Trye this way:
$.post("/oauth/token",body,
function(data, status) {
alert("Data: " + data + "\nStatus: " + status);
});
Hope this helps

Unexpeced token error when setting contentType to application/json

I am sending data using AJAX POST. The data is JSON format. See below. However, I keep getting 'Unexpected token u in JSON at position 0'. Why is this happening? The reason I am setting contentType here is so that the Boolean field checked does not get converted to string.
var data = {
"user": "tom",
"number": 9,
"checked": false
}
$.ajax({
url: url,
method: "POST",
data: data,
contentType: 'application/json',
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Basic " + btoa(username + ":" + password));
},
success: function (success) {
console.log("success");
}
});
When you use contentType: 'application/json', you need to stringify the data yourself:
data: JSON.stringify(data),
As for the error that seems like a response problem. Inspect the actual request in browser dev tools network and see what is actually contained in the reponse body

Wit.ai POST /speech wth HTTP requests

I try to record my voice and send it to /speech method on Wit.ai. So, from my browser, I collect a blob like this and want to execute an $.ajax() request :
recorder && recorder.exportWAV(function (blob) {
callback(blob);
// Ajax request here !
var data = new FormData();
data.append('file', blob);
$.ajax({
url : "https://api.wit.ai/speech?v=20171010",
headers: {
'X-Requested-With': 'JSONHttpRequest',
'Content-Type': 'audio/wav',
'Authorization' : 'Bearer OHROML6TAXxxxxxxxxxxxxSRYOVFCC'
},
type: 'POST',
data: data,
contentType: false,
processData: false,
success: function(data) {
alert(data);
},
error: function(error) {
alert("not so boa!"+JSON.stringify(error));
}
});
recorder.clear();
}, (AudioFormat || "audio/wav"));
All my results are a 400 error ! Bad request ! Or "Mismatch content type".
Any help would be appreciate here.
I tried without success :
recorder && recorder.exportWAV(function (blob) {
callback(blob);
$.ajax({
type: 'POST',
headers: {
'Authorization' : 'Bearer OHROML6TAEDFxxxx5W2SRYOVFCC'
},
url: 'https://api.wit.ai/speech?v=20171010',
data: blob,
contentType: 'audio/wav', // set accordingly
processData: false,
success: function(data) {
alert(data);
},
error: function(error) {
alert("not so boa!"+JSON.stringify(error));
}
});
// Clear the Recorder to start again !
recorder.clear();
}, (AudioFormat || "audio/wav"));
I have still the same issues :
Bad request or Wit doesn"t recognize the sample as a wav audio.
In the sample code you provided, you're submitting a request to Wit using FormData. Per the MDN Web Docs:
FormData uses the same format a form would use if the encoding type were set to multipart/form-data.
But in your request, you're specifying a Content-Type of audio/wav. So you're sending one type of data (multipart/form-data), but saying you're sending a different type (audio/wav).
Per the Wit API docs for POST /speech:
Body
Put your binary data (file or stream) in the body.
To send your audio as binary data, follow this answer to "How can javascript upload a blob?", which includes an example using jQuery.

400 error when converting from ajax to $http?

I am trying to complete a GET request using $http instead of ajax. The call works perfectly with ajax, but when I try to do the same thing with $http I get a 400 (Bad Request) error. I believe I am following the Angular documentation correctly. Any ideas? Hopefully this will also be helpful for others experiencing the same issue.
The ajax code that works:
$.ajax({
type: "GET",
accept: 'application/json',
url: myURL,
headers: {"Authorization": "Basic " + basicKey},
dataType: "json",
contentType: 'application/x-www-form-urlencoded',
data: requestPayload,
async: false
}).done(function(serverData) {
console.log(serverData.access_token);
}).fail(function(error) {
console.log(error);
});
The $http code that does not work:
var basicConfig = {
method: 'GET',
url: myURL,
headers: {
'Authorization': 'Basic ' + basicKey,
'Accept': "application/json",
'Content-Type': 'application/x-www-form-urlencoded'
},
data: requestPayload
}
$http(basicConfig).success(function(data, status){
console.log(status);
}).error(function(data, status){
console.log(status);
});
Thanks in advance.
use params instead of data. data is the request body, used for POST requests, whereas params is for query string variables in GET requests.

how to get access token from bitly using password and username?

$.ajax({
url: 'https://api-ssl.bitly.com/oauth/access_token',
type: 'POST',
contentType: 'application/x-www-form-urlencoded',
dataType: 'json',
data: { Authorization: "Basic " + btoa('myusername' + ":" + 'mypassword#123') },
success: function (result) {
console.log(result);
},
error: function () {
alert("Cannot get data");
}
});
I am trying to get access token from bitly api by providing username and password but it is showing invalid_client_authorization error. Does any one have idea on the same?
Bitly documentation : http://dev.bitly.com/authentication.html#resource_owner_credentials
You are concatenating your username with your authorization header.
Your authorization and content-type should go in the headers object.
There is no 'type' property on jquery ajax method, you probably meant 'method'.
Also, you can't send both dataType:'json' and set the content-type to 'application/x-www-form-urlencoded'
$.ajax({
url: 'https://api-ssl.bitly.com/oauth/access_token',
methdo: 'POST',
contentType: '',
dataType: 'json',
headers: {
'Authorization' : 'Basic ' + [INSERT YOUR HASH HERE],
'Content-Type' : 'application/x-www-form-urlencoded',
}
data: { $.serialize({
username: YOURUSERNAME,
password: YOURPASSWORD
})},
success: function (result) {
console.log(result);
},
error: function () {
alert("Cannot get data");
}
});
This should do it
Fixed #goncalomarques answer:
Removed top level "contentType" and "dataType"
Removed data object (otherwise username and password is sent as clear text, in addition to the hashed username and password in the header)
renamed "methdo" to "method"
Explicitly used btoa() to get Base 64 encoded hash (be aware, does not work in older IE versions)
$.ajax({
url: 'https://api-ssl.bitly.com/oauth/access_token',
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa(YOURUSERNAME + ':' + YOURPASSWORD),
'Content-Type': 'application/x-www-form-urlencoded',
},
success: function(result) {
console.log("success");
console.log(result);
},
error: function(response) {
console.log("Cannot get data");
console.log(response);
}
});
Note:
I have this example working, but was unable to get it working with the built-in Stackoverflow editor ("Run snippet") due to cross origin exceptions.

Categories