I'm trying to use Microsoft Azure OCR API service to extract some text from an image.
The image I have for sending to the API service has a "data:image/png; base64, " structure and therefore I can't send it with content-type "application/json".
I tried sending it with content-type "multipart/form-data" or "application/octet-stream", but it also fails...
// this "url" gives me the "data:data:image/png;base64, " code
var sourceImageUrl = document.getElementById("myImage").src;
// Perform the REST API call.
$.ajax({
url: uriBase + "?" + $.param(params),
// Request headers.
beforeSend: function(jqXHR){
jqXHR.setRequestHeader("Content-Type","multipart/form-data");
jqXHR.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
},
type: "POST",
// Request body.
data: [sourceImageUrl]
})
.done(function(data) {
// Show formatted JSON on webpage.
$("#responseTextArea").val(JSON.stringify(data, null, 2));
})
.fail(function(jqXHR, textStatus, errorThrown) {
// Display error message.
var errorString = (errorThrown === "") ?
"Error. " : errorThrown + " (" + jqXHR.status + "): ";
errorString += (jqXHR.responseText === "") ? "" :
(jQuery.parseJSON(jqXHR.responseText).message) ?
jQuery.parseJSON(jqXHR.responseText).message :
jQuery.parseJSON(jqXHR.responseText).error.message;
alert(errorString);
});
I am bit confused about how I should be sending the image or if I should do some transformations.
Which content-type should I be using to do a proper request?
Should I change the encoding of the image source? How?
Thank you all!
I finally got it working by adding a makeBlob function that returns a blob out of a base64 code. I also set the content-type to "application/octet-stream".
Final code looks like this:
function makeblob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, { type: contentType });
return blob;
}
function recognizeText() {
imageToSend = image.src;
binDataImage = imageToSend.replace("data:image/png;base64,","");
// Perform the REST API call.
$.ajax({
url: uriBase + "?" + $.param(params),
// Request headers.
beforeSend: function(jqXHR){
jqXHR.setRequestHeader("Content-Type","application/octet-stream");
jqXHR.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
},
type: "POST",
// Request body.
data: makeblob(binDataImage, 'image/jpeg'),
cache: false,
processData: false
})
.done(function(data) {
// Show formatted JSON on webpage.
$("#responseTextArea").val(JSON.stringify(data, null, 2));
})
.fail(function(jqXHR, textStatus, errorThrown) {
// Display error message.
var errorString = (errorThrown === "") ?
"Error. " : errorThrown + " (" + jqXHR.status + "): ";
errorString += (jqXHR.responseText === "") ? "" :
(jQuery.parseJSON(jqXHR.responseText).message) ?
jQuery.parseJSON(jqXHR.responseText).message :
jQuery.parseJSON(jqXHR.responseText).error.message;
alert(errorString);
});
};
Related
I don't know why my code is giving error while making the ajax call and not responding or working at all. I ran this on an html file. I took this function - getParameterByName() from another stackoverflow answer.tweet-container tag is down the code below outside this script and an empty division.I tried some jquery also.
<script>
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
$(document).ready(function(){
console.log("working");
var query = getParameterByName("q")
// console.log("query");
var tweetList = [];
function parseTweets(){
if (tweetList == 0){
$("#tweet-container").text("No tweets currently found.")
} else {
//tweets are existing, so parse and display them
$.each(parseTweets, function(key, value){
//console.log(key)
// console.log(value.user)
// console.log(value.content)
var tweetKey = value.key;
var tweetUser = value.user;
var tweetContent = value.content;
$("#tweet-container").append(
"<div class=\"media\"><div class=\"media-body\">" + tweetContent + "</br> via " + tweetUser.username + " | " + View + "</div></div><hr/>"
)
})
}
}
$.ajax({
url:"/api/tweet/",
data:{
"q": query
},
method: "GET",
success:function(data){
//console.log(data)
tweetList = data
parseTweets()
},
error:
function(data){
console.log("error")
console.log(data)
}
})
});
</script>
strong text
Fix the quotes to resolve your syntax error:
$("#tweet-container").append("<div class=\"media\"><div class=\"media-body\">" + tweetContent + " </br> via " + tweetUser.username + " | " + "View</div></div><hr/>")
With the following code I receive a 404 (Not Found) error. I can see that the workflow.asmx URL is correct and I can access it through a browser. I've used similar code in the past on other projects.
function StartExpenseReportToPdfWorkflow(itemId) {
var targetUrl = "../_vti_bin/workflow.asmx";
var listName = "Expense Reports";
var itemUrl = getUrlForListItemId(listName, itemId);
var soapEnv = [];
soapEnv.push("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
soapEnv.push("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
soapEnv.push(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"");
soapEnv.push(" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");
soapEnv.push("<soap:Body>");
soapEnv.push("<StartWorkflow xmlns=\"http://schemas.microsoft.com/sharepoint/soap/workflow/\">");
soapEnv.push("<item>" + itemUrl + "</item>");
soapEnv.push("<templateId>" + expenseReportWorkflowTemplateId + "</templateId>");
soapEnv.push("<workflowParameters><data>");
soapEnv.push("</data></workflowParameters>");
soapEnv.push("</StartWorkflow>");
soapEnv.push("</soap:Body>");
soapEnv.push("</soap:Envelope>");
//get web service url:
var spsdiscoUrl = $("head link[rel='alternate']:eq(0)").attr("href");
var spWSUrlPrefix = spsdiscoUrl.substr(0, spsdiscoUrl.length - 13);
$.ajax({
cache: false,
url: targetUrl, //spWSUrlPrefix + "workflow.asmx",
beforeSend: function (xhr) {
xhr.setRequestHeader("SOAPAction",
"http://schemas.microsoft.com/sharepoint/soap/workflow/StartWorkflow");
},
type: "POST",
dataType: "xml",
data: soapEnv.join(""),
complete: function (msg) {
if (msg.status === 200) { } else {
//Failure
jsUtil.throwError("Well, this is awkward. Something went wrong and we're really sorry. " + msg.statusText, "Error calling Published Workflow: " + msg.statusText);
}
},
contentType: "text/xml; charset=utf-8"
});
}
function getUrlForListItemId(listName, itemId) {
var domain = document.domain;
var spsdiscoUrl = $("head link[rel='alternate']:eq(0)").attr("href");
var webPrefix = spsdiscoUrl.substr(0, spsdiscoUrl.length - 22);
return window.location.protocol + "//" + domain + webPrefix + "Lists/" + listName + "/" + itemId + "_.000";
}
The problem was caused by an incorrect list name. The correct name is "ExpenseReports" without the space. The 401 error led me to believe that there was a problem accessing the workflow.asmx web service itself. After several hours of checking and rechecking, I finally spotted the error.
I am trying to load soundcloud likes (used to be favorites), but I am not getting any results from the ajax query.
This is the url I am trying to load: http://soundcloud.com/gazebo-fm/likes
function soundCloudTrackData(linkUrl) {
var url = soundCloudApiUrl(linkUrl, soundcloudApiKey);
$.ajax({
url: url,
dataType: 'jsonp',
cache: false
}).done(function( data ) {
console.log(data);
}).fail(function(jqXHR, textStatus, errorThrown) {
alert('Soundcloud process error: ' + jqXHR.responseText);
});
}
function soundCloudApiUrl(url, soundcloudApiKey) {
var useSandBox = false;
var domain = useSandBox ? 'sandbox-soundcloud.com' : 'soundcloud.com'
return (/api\./.test(url) ? url + '?' : 'http://api.' + domain +'/resolve?url=' + url + '&') + 'format=json&consumer_key=' + apiKey +'&callback=?';
};
change the url to http://soundcloud.com/gazebo-fm/favorites
/likes is used in new soundcloud's api, which is not yet documented.
I have a HTML form for filling the personal profile, which includes String and Images. And I need to post all these data as JsonObject with one backend api call, and the backend requires the image file sent as binary data. Here is my Json Data as follow:
var profile = {
"userId" : email_Id,
"profile.name" : "TML David",
"profile.profilePicture" : profilePhotoData,
"profile.galleryImageOne" : profileGalleryImage1Data,
"profile.referenceQuote" : "Reference Quote"
};
and, profilePhotoData, profileGalleryImage1Data, profileGalleryImage2Data, profileGalleryImage3Data are all image Binary data(Base64).
And here is my post function:
function APICallCreateProfile(profile){
var requestUrl = BASE_URL + API_URL_CREAT_PROFILE;
$.ajax({
url: requestUrl,
type: 'POST',
data: profile,
dataType:DATA_TYPE,
contentType: CONTENT_TYPE_MEDIA,
cache:false,
processData:false,
timeabout:API_CALL_TIMEOUTS,
success: function (response) {
console.log("response " + JSON.stringify(response));
var success = response.success;
var objectData = response.data;
if(success){
alert('CreateProfile Success!\n' + JSON.stringify(objectData));
}else{
alert('CreateProfile Faild!\n'+ data.text);
}
},
error: function(data){
console.log( "error" +JSON.stringify(data));
},
failure:APIDefaultErrorHandler
})
.done(function() { console.log( "second success" ); })
.always(function() { console.log( "complete" ); });
return false;
}
But still got failed, I checked the server side, and it complains about the "no multipart boundary was found".
Can anyone help me with this, thanks:)
Updates:
var DATA_TYPE = "json";
var CONTENT_TYPE_MEDIA = "multipart/form-data";
I think I found the solution with vineet help. I am using XMLHttpRequest, and didn't set the requestHeader, but it works, very strange. But hope this following can help
function APICallCreateProfile(formData){
var requestUrl = BASE_URL + API_URL_CREAT_PROFILE;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function()
{
if (xhr.readyState==4 && xhr.status==200){
console.log( "profile:" + xhr.responseText);
}else if (xhr.readyState==500){
console.log( "error:" + xhr.responseText);
}
}
xhr.open('POST', requestUrl, true);
// xhr.setRequestHeader("Content-Type","multipart/form-data; boundary=----WebKitFormBoundarynA5hzSDsRj7UJtNa");
xhr.send(formData);
return false;
}
Why to reinvent the wheel. Just use Jquery Form Plugin, here. It has example for multipart upload as well.
You just need to set input type as file. You will receive files as input stream at server (off course they will be multipart)
I'm trying to make a simple AJAX call to the Justin TV API, which seems to be failing consistently.
When making the AJAX call with url1, the console reports Object { readyState=4, status=200, statusText="success"}, yet it falls into the error function of the AJAX call. When visiting the URL with my browser, I notice the returned data is [{ ... json ...}].
When making the AJAX call with 'url', the call passes, entering the success function. I notice the returned object is { ...json... }.
How do I get a valid JSON object out of the AJAX request for url1?
Here's a snip of what I'm doing:
var url1 = "http://api.justin.tv/api/stream/list.json"
var url = "https://api.twitch.tv/kraken/streams/";
channelNames = "";
for (channelName in streams)
{
channelNames = channelNames + ',' + channelName;
}
channelNames = channelNames.slice(1);
console.log(channelNames);
console.log(url1);
$.ajax({
url: url1,
type: 'GET',
crossDomain: true,
dataType: 'jsonp',
data: { channel : channelNames },
success: function(data)
{
console.log(data);
if(data.streams.length > 0)
{
$("#streamStatus").html("<ul class='zebra'>");
for(i = 0; i < data.streams.length; i++)
{
stream = data.streams[i];
channel = data.streams[i].channel;
listItem = "<li id='stream"+i+"'>";
streamName = "<span class='name'>" + streams[stream.name.slice(10)] + "</span>";
viewers = "<span class='viewers'>viewers:" + stream.viewers + "</span>";
gameName = "<div class='game'>" + ((channel.game != null) ? channel.game : "No Game Specified") + "</div>";
listItem += streamName + viewers + gameName + "</li>";
screenCap = "<div class='screenCap' style='display:none;'>" + channel.screen_cap_url_small + "</div>"
$("#streamStatus ul.zebra").append(listItem);
$("#streamStatus ul.zebra").append(screenCap);
//console.log(channel);
}
$("#streamStatus").append("</ul>");
}
},
error: function(data)
{
console.log(data);
}
EDIT: Here is the working solution...
var url1 = "http://api.justin.tv/api/stream/list.json"
var url = "https://api.twitch.tv/kraken/streams/";
channelNames = "";
for (channelName in streams)
{
channelNames = channelNames + ',' + channelName;
}
channelNames = channelNames.slice(1);
console.log(channelNames);
console.log(url1);
$.ajax({
url: url1,
type: 'GET',
crossDomain: true,
dataType: 'jsonp',
jsonp: 'jsonp',
data: { channel : channelNames },
success: function(data)
{
...
},
error: function(data)
{
console.log(data);
}
You're passing jsonp as the dataType in the ajax call. They're not interchangeable.
As you've noted yourself, the data returned from url1 is JSON, not JSONP: JSONP requires wrapping the returned JSON data in a javascript function call.
A mismatch like this between dataType and the data in the response body will always cause the ajax call to fail.