How can I save a response of HTTP GET Request in variable? - ajax

Here is my API code
#GetMapping("/api/test")
public String test() {
return "hello";
}
Then I will send request to this API by using ajax.
function test() {
$.ajax({
type: "GET",
url: "/api/test",
success: function(response) {
}
})
}
I want to save the value of ajax call response (In this case "hello") in variable. Please let me know how to do it.

Several ways of doing it !
As far as only a String message is concerned you can just store it like below
`var myResponse=response;`
Alternatively, you can also access values if response is an object (JSON reponse I mean)
for e.g. `var resp=response.message; //Assuming message is a key in response JSON`
For testing, use alert(response) or console.log(response) to see how your response is coming and manipulate accordingly !
Feel free to refer this link for detailed Ajax walkthrough https://www.tutorialspoint.com/jquery/jquery-ajax.htm
Hope these helps!

Related

ValidateAntiforgeryToken failure

I'm facing problem of AntiforgeryToken verification.
I'm sending data like this:
var data = {
__RequestVerificationToken: '#GetAntiXsrfRequestToken()',
Id: id,
ResolverGID: resolverGID
};
I'm using fetch method to send POST data
return fetch(fetchURL, JSON.stringify(data))
.then(async (response) => {
return response.json();
})
.catch(() => {
return false;
});
and sent data looks like this:
Id: 98
ResolverGID: "XXXX"
__RequestVerificationToken: "CfDJ8EaAHBfZaBJBuxJJzC77RytBbhcw-gV2E_x0mfFVVhCy0BSmE9L5w5jzIW-7CrY_pCClHed5Ez6D3vuDj5rWWyoKr90MSOu-uBMGUuoF9iIXQ9y4vUjY_sxa5fghGEo-Xcp5KC541aGD407Fz9D9itZMeID5jqRv61IRINTSwJH_2yRvgg-BC1cDAriut22Oyw"
but my method returns error 400: Bad request.
When I use [IgnoreAntiforgeryToken] instead of [ValidateAntiForgeryToken] attribute it works, but with antiforgery token validation it does not work.
When I use the same token function in modal window to send data it's ok, no problem occurs...
can somebody help me?
Thanks
Maybe I have found the solution to this.
[ValidateAntiForgeryToken] works only when FormData format is sent, so I had to send data like this:
let data = new FormData();
data.append('Id', id);
data.append('ResolverGID', resolverGID);
data.append('__RequestVerificationToken', '#GetAntiXsrfRequestToken()');
and then it works as expected.

ApplePay completeMerchantValidation fails

We have a site example.com behind ssl that runs a page with ApplePay.
We've got a server side that returns a Merchant Session that looks like the following:
{"epochTimestamp":1581975586106,"expiresAt":1581979186106,"merchantSessionIdentifier":"SSH8E666B0...","nonce":"1239e567","merchantIdentifier":"...8557220BAF491419A...","domainName":"example.com","displayName":"ApplePay","signature":"...20101310f300d06096086480165030402010500308..."}
We receive this response in session.onvalidatemerchant as a string and convert it to a Json Object and pass to session.completeMerchantValidation.
As a result we get the following error:
Code: "InvalidAccessError"
Message: "The object does not support the operation or argument"
We run the following code on our page:
.....
session.onvalidatemerchant = (event) => {
const validationURL = event.validationURL;
getApplePaySession(validationURL).then(function (response) {
try {
let resp = JSON.parse(response);
session.completeMerchantValidation(resp);
} catch (e) {
console.error(JSON.stringify(e));
}
});
};
....
Additional questions:
Is the object described above a "correct" Merchant Session opaque that needs to be passed to completeMerchantValidation or it's missing some fields?
Is this object needs to be passed as is or it needs to be base64 encoded?
Does it need to be wrapped into another object?
Any help or lead is greatly appreciated.

How to send call to JSP from AJAX?

This servlet code,here 1st i want to send return message(if message!=null) to the Ajax for alert and 2nd one if message==null i want to call another jsp with pass the list to this jsp.
if(message!=null){
response.setContentType("text/plain");
response.getWriter().write(message);
}else{
JSONObject jobj = new JSONObject();
String urlToRedirect = "SearchEmployee.jsp";
jobj.put("url",urlToRedirect );
response.getWriter().write(jobj.toString());
}
Here i cant understand how to call this jsp url in else part
$.ajax({
type:"POST",
url:'../SearchEmployeeServlet',
data:$('#DisplayEmployeeListForm').serialize(),//$('form').serialize();
success:function(msg){
if(msg!=""){
alert(msg);
window.location.reload(true);
}else{
....here i want to call 2nd jsp
}
}
});
You could just forward the request server-side, to avoid needing the client to make a second request:
request.getRequestDispatcher("SearchEmployee.jsp").forward(request, response);
Or alternatively, you could send an HTTP redirect response, so the client should handle the redirection to the second request automatically:
response.sendRedirect(response.encodeRedirectUrl("SearchEmployee.jsp"));
Note that how you handle this in the JavaScript depends on the datatype you expect to receive from SearchEmployee.jsp. For example, if it is XML and you have set the response content-type to text/xml jQuery will parse it and pass you an XML DOM object to your success function:
success:function(msg) {
if (msg instanceof XMLDocument) {
// handle list
} else {
alert(msg);
window.location.reload(true);
}
}
If you're expecting HTML, this may be returned as a string, so you could test to see if your returned string starts with some HTML. For example, if your HTML will always start with a <ul> tag:
success:function(msg) {
if (msg.startsWith("<ul>")) { // note you may need to do msg = $.trim(msg) first
// handle list
} else {
alert(msg);
window.location.reload(true);
}
}
If you don't want to auto-forward as suggested above and you'd rather stick with your current approach, there are a few things you'll need to change.
Using if(msg!="") in your success function is bad as that will return true as long as the server does not return an empty response (so in both cases you'll get an alert).
The first thing to do is to add a content-type header to your servlet code to indicate you're returning JSON in the second case:
response.setContentType("application/json");
response.getWriter().write(jobj.toString());
Now when jQuery handles the response, it will attempt to parse it as JSON before calling the success function. As such, you can now test in your success function whether the argument jQuery has given you is an object or a string:
success:function(msg){
if (typeof msg === "object") {
// you got the JSON response
$.ajax({
url: msg.url,
// etc...
});
} else {
// you got the plain text response
alert(msg);
window.location.reload(true);
}
}
Just make the ajax request in else part as you did above.
$.ajax({url: "jsp url", success: function(result){
}});
Find more information here

Asynchronously populate Sammy.Storage cache

I'm having difficulty accessing requestJSON on a jQuery $.ajax object outside of the success callback. If I do:
var ajax_request = $.ajax({
dataType: 'json',
contentType: 'application/json'
});
console.log(ajax_request.responseJSON);
// this results in `undefined`
How can I access the responseJSON without adding a .success() callback? If I inspect ajax_request in Firebug, I can see the responseJSON property, and the data I expect, but I can't access it via:
ajax_request.responseJSON
More specifically, I'm building an SPA using Sammy and Knockout. In some routes, I need to be able to get JSON from cache, and if it doesn't exist, get the value from a service call and then set it into cache:
var cached_json = storage.fetch('cached_json', function() {
// make service call
return $.getJSON(url);
});
event_context.render('template.tpl', {'json': cached_json}).appendTo('#my-target');
But, of course, calling storage.fetch doesn't cause the rest of the code to pause until $.getJSON is complete. This is the part I can't quite figure out how to structure.
here's how i would implement it
responseJSON = "";
$.get("myurl.php",function(jdata){
responseJSON = jdata;
},"json");
i like to see the ajax method at a glace, but in your case you can do the same by
....
success : function(jdata){ responseJSON = jdata; }
....
PS: i believe that initializing the blank responseJSON is not required since any variable without var is in global scope, but it would help for clarity
I ended up solving this by creating a deferred object that gets or creates the value I need:
function get_or_create_cache(storage, key, service_endpoint) {
return $.Deferred(function(deferred) {
var c = storage.get(key);
if (c === null || c === undefined) {
$.when(jsonp_service_request(service_endpoint)).done(function(json) {
storage.set(key, json);
deferred.resolve(json);
});
}
else {
deferred.resolve(c);
}
}).promise();
}
In this function, storage refers to a Sammy.Storage instance. jsonp_service_request is a local function that returns a jsonp response, taking into account the location.hostname for local development, where I'm pointing to local.json files, or a remote environment, where I'm calling into an actual API. jsonp_service_request returns an $.ajax function.
Then in my Sammy route, I can do:
this.get('#/', function(event_context) {
$.when(get_or_create_cache(storage, 'my-cache-key', 'service-endpoint'))
.then(function(json) {
event_context.render('my-template.template', {'value-name': json})
.appendTo('#my-target');
});
});

Deserialize HttpError ModelState

Wit the latest webapi bits I now have
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
My client is an MVC website that reads the value from the response. I finally got it to read the HttpError object from the response, but loading the ModelState is... not intuitive to say the least.
Is there a cleaner way to write this?
var httpError = response.Read<HttpError>();
var errors = httpError["ModelState"] as JObject;
foreach (var error in errors)
foreach (var message in error.Value.Values<string>())
{
modelState.AddModelError(error.Key, message);
}
While an error response, as you've identified, can readily be deserialised into an HttpError, the ModelState value within it only ends up as a JObject.
You've probably already tried something like:
var errors = ((JObject)errorMsg["ModelState"])
.ToObject<ModelStateDictionary>();
Or maybe:
var errors = ((JObject)errorMsg["ModelState"])
.ToObject<Dictionary<string, ICollection<ModelError>>>();
And found that it won't convert. The best alternative I could find was:
var errors = ((JObject)errorMsg["ModelState"])
.ToObject<Dictionary<string, IList<string>>>();
Which makes your iteration marginally neater:
foreach (var err in errors)
foreach (var msg in err.Value)
{
modelStateDictionary.AddModelError(err.Key, msg);
}
The problem, as I see it, is a string won't deserialise to a ModelError instance, and is further compounded by ModelErrorCollection unfortunately hiding its base class constructor of Collection(IList list).
How are you making the API calls? Client-side? If so, I noticed Brad Wilson using the below format for receiving AJAX responses via jQuery in a recent demo. This may not be what you're looking for but it's been working well for me:
$.ajax({
url: "/apicontorller/action/",
contentType: "application/json",
type: "POST",
data: jsonData,
statusCode: {
200: function (data) {
},
404: function () {
alert('404');
},
400: function () {
alert('invalid');
},
500: function () {
alert('error');
},
// ...
}
});
The nice thing about this is you can handle the actual HTTP status codes. In my experience, error messages/data can be accessed by providing a parameter to the predicate function. I'm still learning about REST and the WebAPI platform so if anyone can provide a better implementation, I certainly welcome it!

Resources