I host my MVC API in server 'A'.
I tried to call API using jquery ajax call from native server (server 'A'). it's working fine as expected.
But, when tried to call API from server 'B'. I got an error.
No 'Access-Control-Allow-Origin' header is present on the requested resource
My ajax call like below
$.ajax({
url: Url,
type: "GET",
data: Data,
contentType: "application/json charset=utf-8",
async: false,
cache: false,
error: function (xhr, ajaxOptions, thrownError) {
console.log("Exception in ajaxRequest - " + xhr.status + ' - ' + thrownError);
},
success: function (data) {
ResultData = $.parseJSON(data);
}
});
Related
I have a .Net website, hosted on an intranet web server. On the .Net site I have a basic jquery ajax call to our mirth machine. I'm trying to hit the client apis that are provided with the base install of mirth.
We are running mirth 3.9.1, with a default mirth.properties page, so the CORS settings should be correct.
I've tried a variety of settings in mirth.properties (and restarted mcservice between changes) and a variety of $.ajax settings, but cannot seem to find the right mix.
According to this answer: (https://stackoverflow.com/a/47096927/505829), I should be able to use basic authentication, but even if I have to make two calls, I'm ok with that, I just need something that works. Though one call would be preferred.
Here is the ajax call
$.ajax
({
type: "GET",
url: "https://ngmaintst01:8443/api/channels",
dataType: 'json',
// username: username,
// password: password,
// crossDomain: true,
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Basic ' + btoa(username + ":" + password));
},
xhrFields: {
withCredentials: true
},
// headers: {
// "Authorization": "Basic " + btoa(username + ":" + password)
// },
success: function () {
alert('success');
}
});
Here is the mirth properties:
# CORS headers
server.api.accesscontrolalloworigin = *
server.api.accesscontrolallowcredentials = false
server.api.accesscontrolallowmethods = GET, POST, DELETE, PUT
server.api.accesscontrolallowheaders = Content-Type
server.api.accesscontrolexposeheaders =
server.api.accesscontrolmaxage =
If I take the one call aproach, illistrated above, in chromes dev console I get:
(failed)net::ERR_FAILED
If I take a two call approach (below), the first call is successful (code 200), and the second gets the same error as the single call approach '(failed)net::ERR_FAILED', This time it appears the second call does NOT go out with the cookie session data, which is why a single call approach may be ideal.
$.ajax({
type: 'POST',
url: 'https://' + APPLIANCE+':8443/api/users/_login',
contentType: 'application/x-www-form-urlencoded',
dataType: 'xml',
data: { username: username, password: password },
success: function (data, textStatus, jqXHR) {
//alert(textStatus);
$.ajax({
type: 'GET',
url: 'https://' + APPLIANCE + ':8443/api/channels/' + channelid + '/statistics',
dataType: 'xml',
crossDomain: true,
xhrFields: { withCredentials: true },
//data: data,
//success: function(data, textStatus, jqXHR){ alert(textStatus); },
//error: function(jqXHR, textStatus, errorThrown){ alert(textStatus);}
});
},
error: function (jqXHR, textStatus, errorThrown) { alert(textStatus); }
});
I was able to get this working with some help from the mirth folks on slack. There is a "problem" in that, as far as I know, it will only support one web server. So I either need to have both my test and prod site on this one server, or no test.
Alternatively, I will just use a proxy back end service to circumvent cors altogether. So my local js will call my local proxy server, and forward the request on to mirths api.
Still, for posterity, here is how to get cors to work.
(One possible feature for mirth to implement would be dynamic accesscontrolalloworigin, where you provide an 'access list' of domains, and so long as the request is coming from one of those domains, it spits out, dynamically, that servers name. This would enable me to have multiple servers calling these apis. ala Access-Control-Allow-Origin Multiple Origin Domains?)
# CORS headers
server.api.accesscontrolalloworigin = https://MyDomainServer
server.api.accesscontrolallowcredentials = true
server.api.accesscontrolallowmethods = GET,HEAD,OPTIONS,POST,PUT
server.api.accesscontrolallowheaders = Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization
server.api.accesscontrolexposeheaders =
server.api.accesscontrolmaxage =
$.ajax
({
type: "GET",
url: "https://MirthAppliance:8443/api/channels",
dataType: 'json',
xhrFields: {
withCredentials: true
},
headers: {
"Authorization": "Basic " + btoa(username + ":" + password)
},
success: function () {
//alert('success');
},
error: function (xhr, status, error) {
var errorMessage = xhr.status + ': ' + xhr.statusText
// alert('Error - ' + errorMessage);
}
});
I want to call a webservice from client side using jquery ajax(with custom headers). And I almost did that. I had set Access-Control-Allow-Origin to force.com and salesforce.com since I'm calling the webservice from salesforce.
When I try to call that API without the custom headers, its getting the response where as when I called with the headers, its not getting the response.
With custom headers
jQuery.ajax({
type: 'POST',
contentType: 'application/x-www-form-urlencoded',
url: 'https://xxx.myclient.com/xxx/xxx/register',
beforeSend: function(xhr) {
xhr.setRequestHeader('orgid', '00D90000000oxxxx');
xhr.setRequestHeader('userid', '00590000001Dxxxxxx');
},
success: function(response) {
alert('success' + JSON.stringify(response));
},
error: function(jqXHR, textStatus) {
alert('jqXHR : ' + JSON.stringify(jqXHR) + ' textStatus : ' + textStatus);
}
});
also tried with
jQuery.ajax({
type: 'POST',
contentType: 'application/x-www-form-urlencoded',
url: 'https://xxx.myclient.com/xxx/xxx/register',
headers: {
"orgid": "00D90000000oxxxx",
"userid": "00590000001Dxxxxxx",
},
success: function(data) {
alert(JSON.stringify(data));
},
error: function(jqXHR, textStatus) {
alert('jqXHR : ' + JSON.stringify(jqXHR) + ' textStatus : ' + textStatus);
}
});
But in both the above cases it is not hitting the server and getting the error message
When I'm not using any headers, then its hitting the server
jQuery.ajax({
type: 'POST',
contentType: 'application/x-www-form-urlencoded',
url: 'https://xxx.myclient.com/xxx/xxx/register',
success: function(response) {
alert('success' + JSON.stringify(response));
},
error: function(jqXHR, textStatus) {
alert('jqXHR : ' + JSON.stringify(jqXHR) + ' textStatus : ' + textStatus);
}
});
Its getting the success response
In response headers it shows that
Access-Control-Allow-Headers: Content-Type
Only content-type is there, Is that the problem?
Whether we need to add our custom headers here?
And when I analysed the network using firefox firebug, it is showing as given below
POST Register (without any headers passed)
OPTIONS Register (with custom headers)
I dont know why this is happening
Can any one help.
Thanks in Advance ..:)
Try adding your custom headers (orgId and userId) in the "Access-Control-Allow-Headers" list of the service you are calling.
I'm trying to get some information from a different domain, the domain allows only jsonp call - others get rejected. How can I get the content instead of execution? Because I get an error in response. I don't need to execute it, I just need it in my script. In any format (the response is json but js doesn't understand it).
I can't affect on that domain so it's impossible to change something on that side.
Here's my code:
$.ajax({
url: url + '?callback=?',
crossDomain: true,
type: "POST",
data: {key: key},
contentType: "application/json; charset=utf-8;",
async: false,
dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'jsonpCallback',
error: function(xhr, status, error) {
console.log(status + '; ' + error);
}
});
window.jsonpCallback = function(response) {
console.log('callback success');
};
There are a few issues with your $.ajax call.
$.ajax({
url: url + '?callback=?',
// this is not needed for JSONP. What this does, is force a local
// AJAX call to accessed as if it were cross domain
crossDomain: true,
// JSONP can only be GET
type: "POST",
data: {key: key},
// contentType is for the request body, it is incorrect here
contentType: "application/json; charset=utf-8;",
// This does not work with JSONP, nor should you be using it anyway.
// It will lock up the browser
async: false,
dataType: 'jsonp',
// This changes the parameter that jQuery will add to the URL
jsonp: 'callback',
// This overrides the callback value that jQuery will add to the URL
// useful to help with caching
// or if the URL has a hard-coded callback (you need to set jsonp: false)
jsonpCallback: 'jsonpCallback',
error: function(xhr, status, error) {
console.log(status + '; ' + error);
}
});
You should be calling your url like this:
$.ajax({
url: url,
data: {key: key},
dataType: 'jsonp',
success: function(response) {
console.log('callback success');
},
error: function(xhr, status, error) {
console.log(status + '; ' + error);
}
});
JSONP is not JSON. JSONP is actually just adding a script tag to your <head>. The response needs to be a JavaScript file containing a function call with the JSON data as a parameter.
JSONP is something the server needs to support. If the server doesn't respond correctly, you can't use JSONP.
Please read the docs: http://api.jquery.com/jquery.ajax/
var url = "https://status.github.com/api/status.json?callback=apiStatus";
$.ajax({
url: url,
dataType: 'jsonp',
jsonpCallback: 'apiStatus',
success: function (response) {
console.log('callback success: ', response);
},
error: function (xhr, status, error) {
console.log(status + '; ' + error);
}
});
Try this code.
Also try calling this url directly in ur browser and see what it exactly returns, by this way You can understand better what actually happens :).
The jsonpCallback parameter is used for specifying the name of the function in the JSONP response, not the name of the function in your code. You can likely remove this; jQuery will handle this automatically on your behalf.
Instead, you're looking for the success parameter (to retrieve the response data). For example:
$.ajax({
url: url,
crossDomain: true,
type: "POST",
data: {key: key},
contentType: "application/json; charset=utf-8;",
async: false,
dataType: 'jsonp',
success: function(data){
console.log('callback success');
console.log(data);
}
error: function(xhr, status, error) {
console.log(status + '; ' + error);
}
});
You can also likely remove the other JSONP-releated parameters, which were set to jQuery defaults. See jQuery.ajax for more information.
I'm trying to get JSON data from another domain.
It returns status 200 but invokes an error in the callback function.
Is it possible to get the raw data or html or even just text when I get into the error callback?
Why is xhr.responseText undefined?
Here is part of my code:
$.ajax({
type: 'POST',
url: 'http://timetable.nctu.edu.tw/?r=main/get_cos_list',
dataType: 'jsonp',
crossDomain: true,
async: false,
data:{m_acy:'**',m_sem:'**',m_degree:'**',m_dep_id:'**',m_group:'**',
m_grade:'**',m_class:'**',m_option:'cos_code',m_crsname:'**',m_teaname:'**',
m_cos_id:'**',m_cos_code:'DAM1346',m_crstime:'**'},
jsonp: true,
success: function(json) {
$('#jjjj').html(json);
},
error: function(xhr, textStatus, errorThrown) {
$('#content').append("readyState: "+xhr.readyState+"<br>status: "+xhr.status+"<br>responseText: "+xhr.responseText+"<br><hr>");
alert('Ajax request error.' + xhr.responseText + xhr.responseData + errorThrown);
},
complete: function(xhr, textStatus)
{
alert(xhr.responseText + xhr.responseHtml);
alert(h.responseHtml);
}
});
I need to get xml document from a server, then client signs it and sends back to server.
At server side I have web method which saves document:
[WebMethod]
public static void SaveSignedDocument(string SignedData)
{
SignedCms signedCms = new SignedCms();
....
}
Then, I get document from a server and after success receive it I make client to sign it and send back. Here is Javascript
// get xml to sign
$.ajax({
type: "POST",
url: "Default.aspx/GetXMLReceipt",
data: "{'ITN': " + ITN + " }",
contentType: "application/json; charset=utf-8",
dataType: "xml",
success: function (xml) {
// xml file was got
var xmlString = xmlToString(xmlData);
// Sign data
var SignedData = SignData(xmlString);
// Send it to server
$.ajax({
url: 'Default.aspx/SaveSignedDocument',
data: "{ 'SignedData': '" + SignedData + "' }",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data){
alert('Document was successfully sent!');
}
error: function (data, status, jqXHR) {
alert('Send signed data failed - ' + jqXHR);
}
});
},
error: function (data, status, jqXHR) {
alert('Get data failed - ' + jqXHR);
}
});
The problem is that none of the alert at second requests ever fire. If I change request to synchronous everything is ok but why it does not work like written above? The server receives nothing and if we look to network traffic I see that request was interrupted. Why?
Encode your data properly, do not use any string concatenations. Here's the correct way:
data: JSON.stringify({ ITN: ITN }),
and on your second AJAX request:
data: JSON.stringify({ SignedData: SignedData })
The JSON.stringify method will ensure that you are sending valid JSON to your server by properly encoding the argument.