I have a angularjs function which is calling a server side url and getting responses. This server side some times returning a xml response. sometimes returning a blog as the response. Can't predict. If I set the response type to "blob" in client side, it is showing image properly. But I cannot handle non blob responses because of xml responses also showing as a blob. Searched a lot in web about converting blob to xml(response containing a xml response). But couldn't find an answer :(
If I remove the response type: "blob", can handle the non blob response but cannot handle blob response.
Is there a way to handle both type of responses in a single method?
this is my angularjs code for getting response
$http({
url: apiConstants.BASE_URL + 'login',
method: "POST",
responseType: "blob",
data: {
"Req": req
},
headers: {
'X-Username': aUser,
'X-Password': aPass,
"Content-Type": "application/xml"
},
dataType: "xml"
}).success(function(data, status) {
console.log(data);
}
If you can manage to set the Content-Type header correctly in the response while serving your blob and xml responses from your server, then you can use the headers() in success callback to handle them accordingly.
$http.post(url, postData)
.then(function(response){
// success callback
var responseType = response.headers('Content-Type');
var actualType = responseType.split(';');
if(actualType[0] === 'application/xml'){
// handle XML files here
}else{
// handle blob files here
}
}, function(error){
// error callback
});
I solved this issue by doing following changes
$http({
url: apiConstants.BASE_URL + 'login',
method: "POST",
responseType: "blob",
data: {
"Req": req
},
headers: {
'X-Username': aUser,
'X-Password': aPass,
"Content-Type": "application/xml"
},
dataType: "xml"
}).success(function(data, status, headers, config) {
var responseType = headers('Content-Type');
if(responseType === 'application/xml;charset=utf-8'){
alert("xml");
}else{
alert("blob");
}
}
Related
I've seen similar incidents such as this. However, none of them seem to encounter the same problem I am having: Making a POST request and getting a 500 Internal Server Error in response.
I'm attempting to convert either of the following AJAX or XHR that I generated from a postman command to the AngularJS method of using the $http service:
The xhr:
var data = "json=<lots of encoded text>";
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://myJenkins.com/job/Ansible_Deploy/build?token=<build_token>");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Authorization", "Basic <auth data>");
xhr.send(data);
The ajax:
var settings = {
"async": true,
"crossDomain": true,
"url": "https://myJenkins.com/job/Ansible_Deploy/build?token=<build_token>",
"method": "POST",
"headers": {
"content-type": "application/x-www-form-urlencoded",
"authorization": "Basic <auth data>"
},
"data": {
"json": "<raw json text>"
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
The broken AngularJS implementation:
var heads = new Headers();
heads.append('Content-Type', 'application/x-www-form-urlencoded');
heads.append('Authorization', 'Basic <auth data>');
$http({
url: "https://myJenkins.com/job/Ansible_Deploy/build?token=<build token>",
method: "POST",
data: <json object>,
headers: heads
}).then(function successCallback(response) {
console.log(response.data);
}, function errorCallback(response) {
console.log(response.statusText);
});
Both of the above Ajax and xhr implementations work fine. As mentioned above, the angular approach is giving me a 500 Internal Server Error.
Any ideas why this may be happening? I can provide specifics if they may help, such as information from the network tab on the chrome inspector. Just let me know what I should take a screenshot of and I'll post it here.
EDIT: As promised in the comments, my solution is below.
$http({
url: "https://myJenkins.com/job/Ansible_Deploy/build?token=<build token>",
method: "POST",
data: 'json=' + JSON.stringify(data),
headers: {
'Accept': "*/*",
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic <auth data>'
}
}).then(function successCallback(response) {
console.log(response.data);
}, function errorCallback(response) {
console.log(response.statusText);
});
EDIT 2: If you stumble upon this question because you're also getting a 500 Internal Server Error and still don't understand how this was resolved, then it was resolved via a combination of ensuring that CORS was setup on the server containing the endpoint (indicated by Crome's inspector throwing Access-Control-* errors) as well as correctly formatting the x-www-form-urlencoded to be accepted by Jenkins, which requires the data being sent to be of the form json={"parameter":[{"name":<key>, "value":<value>}, ...]}. Furthermore, if the value of an entry is a nested then escaping is required. see this answer for more details.
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.
I have jquery ajax query:
var data2 = "data"
var ajaxOptions2 = {
type: "post",
url: "http://localhost:8050/adapter/interface",
data: data2,
dataType: "json",
success: onSuccess,
error: onError,
processData: false,
contentType: "application/json; charset=UTF-8"
};
$.ajax(ajaxOptions2);
and this post request is working properly
I tried to rewrote this to the angular2 http.post:
let bodyString = "data";
let headers = new Headers({ 'dataType': 'json', 'contentType': 'application/json; charset=UTF-8' });
let options = new RequestOptions({ headers: headers, method: RequestMethod.Post});
that.http.post(that.url, bodyString, options)
.map(that.extractData)
.catch(that.handleError)
.subscribe(data => { console.log("test")});
but http.post is returning error:
XMLHttpRequest cannot load http://localhost:8050/adapter/interface. Request header field dataType is not allowed by Access-Control-Allow-Headers in preflight response.
Can you tell why why jquery ajax is working but my http.post dont?
Well the problem is exactly what the error message is stating.
In your post request you are setting the header "dataType" which obviously isn't allowed by the server for the POST or OPTIONS request.
You are not setting this header in your ajax request.
If you want to make it work you either have to remove the header or re-configure your server in order to accept this header instead.
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
);
}
I am currently working on ASP.NET WebApi and Angularjs
WebApi have a method
[System.Web.Http.AcceptVerbs("POST")]
[System.Web.Http.HttpPost]
public HttpResponseMessage SearchAddress(SearchDetails searchDetail)
{
//13.03993,80.231867
try
{
if (!WebSecurity.IsAuthenticated)
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.NotAcceptable);
return response;
}
List<CollegeAddress> CollegeAddress = addressService.GetAddressFromDistance(17.380498, 78.4864948, 2000);
HttpResponseMessage responseData = Request.CreateResponse(HttpStatusCode.Accepted, CollegeAddress);
return responseData;
}
catch (Exception e)
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.NotFound);
return response;
}
}
And I have to call this method from client side.
When I call this method using Ajax, it's not working, the method parameter searchDetail is always null if I use Ajax.
$.ajax({
method: 'POST',
url: rootUrl + '/api/Address/SearchAddress',
async: false,
data: searchDetail,
type: "json",
headers: {
'Content-Type': "application/json; charset=utf-8"
}
}).success(function (response) {
return response;
}).error(function () {
toastr.error('Somthing is wrong', 'Error');
})
But when I call that method via HTTP request, it is working.
$http({
method: 'POST',
url: rootUrl + '/api/Address/SearchAddress',
data: searchDetail,
headers: {
'Content-Type': "application/json; charset=utf-8"
}
}).success(function (response) {
toastr.success('Account Created successfully!', 'Account Created');
return response;
}).error(function () {
toastr.error('Somthing is wrong', 'Error');
})
Why? What is the difference between them? Why is Ajax not working and HTTP is?
jQuery's ajax() sends the data with Content-type: x-www-form-urlencoded.
Angular's $http sends the data with Content-type: application/json
Your server obviously expects JSON, but you set up the $.ajax() call incorrectly for that.
According to the docs:
The method property doesn't seem to exist.
The type property is supposed to determine the type of the request (e.g. 'GET', 'POST', etc.).
In order to change the default content-type to application/json you can use the contentType property.
I have not tried it myself, but something like this should work:
$.ajax({
type: 'POST',
url: rootUrl + '/api/Address/SearchAddress',
async: false,
data: searchDetail,
contentType: 'application/json; charset=utf-8'
});
$.ajax({
method: 'POST',
url: rootUrl + '/api/Address/SearchAddress',
async: false,
data: searchDetail,
I assume that searchDetail is an object. This is what the docs say about the data property:
... It is converted to a query string, if not already a string.
So if the server expects JSON then you have to convert it to JSON first:
data: JSON.stringify(searchDetail),
And as #ExpertSystem has pointed out you have to change method to type.
First you are duplicating the HttpPost, so just keep the second (and remove the namespace)
Second you want search detail to come from the body so decorate it with [FromBody]
[HttpPost]
public HttpResponseMessage SearchAddress([FromBody]SearchDetails searchDetail)
{