Error When Ajax sending two Request to Wicket Server - javascript

I am posting data to the wicket server via ajax when user click.to make the state ,retrieve the data when page loading ,via ajax GET, if only one request is sending then its working fine ,but in second request following error has thrown.
org.apache.wicket.core.request.mapper.StalePageException
How can I send the data to the server via ajax and later load the panel
with the submitted data when user load it.
Code :Java Script
Sending data to the server
function submitdata() {
$.ajax({
url : $('#mark').attr('json:callback.url1'),
type : 'post',
cache : false,
data : ko.toJSON(familyModel),
ntentType : 'application/json',
dataType : 'json',
complete : function() {
} ,
error: function(xhr, status, error){
console.log(xhr);
alert(status);
alert(error);
}
});}
}
Page Load
$(document).ready(function() {
$.ajax({
url : $('#mark').attr('json:callback.url'),
type : 'GET',
cache : false,
contentType : 'application/json',
success: function (data) {
console.log(data);
var parsed = JSON.parse(data);
// ko.mapping.fromJS(data, familyModel);
/ ko.applyBindings(familyModel);
// familyModel=new FamilyModel();
ko.applyBindings(familyModel);
},
error: function(xhr, status, error){
console.log(xhr);
alert(status);
alert(error);
}
});
}
public class AbstractJSONBehavior extends AbstractAjaxBehavior {
public void onRequest() {
RequestCycle requestCycle = RequestCycle.get();
readRequestData(requestCycle);
sendResponse(requestCycle);
}

You are using plain jQuery APIs and Wicket believes that the requests are non-Ajax, so it increments the Page#renderCount counter to prevent using page with stale information.
If you use Wicket.Ajax.post({...}) then Wicket will figure this out automatically.
So you can either use Wicket.Ajax.post() or pass either the request parameters or headers from https://github.com/apache/wicket/blob/master/wicket-request/src/main/java/org/apache/wicket/request/http/WebRequest.java#L40-L48 with value true to the jQuery#ajax().

Related

JSON Parse error when submitting AJAX post to Spring Boot Controller using Thymeleaf

I have a form that I am submitting using AJAX:
var formData = JSON.stringify($('#supportrequest').serializeArray());
$.ajax({
type: "POST",
url: "/updatesupportrequest?bugid=" + $('#requestnum').val(),
data: formData,
success: function(){
console.log("success");
},
error: function(xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
},
complete: function(){
console.log("complete");
},
dataType: "json",
contentType : "application/json"
});
This is picked up by my Spring Boot controller:
#PostMapping("/updatesupportrequest") // Called by the form
public String createSupportRequest(#RequestParam(name = "bugid") int bugid, #RequestBody String requestBody,
Model model) {
System.out.println(bugid);
DatabaseWriteResponse response = writeToDatabaseService
.writeToDatabase(WriteToDatabaseService.PROCEDURE_UPDATESUPPORTREQUEST, requestBody);
System.out.println(response.getResponse());
if (response.getResponse().equals(DatabaseWriteResponse.SUCCESS)) {
return "supportrequest";
}
else {
model.addAttribute("response", response.getResponse());
model.addAttribute("errorMsg", response.getMsg());
return "error";
}
}
The actual saving of the data works just fine. The problem is that the controller returns the "supportrequest.html" page. AJAX then throws a parse error:
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
Looking at the xhr.responseText, we get the page back:
responseText: "<!--\r\n TODO\r\n - Dev page has some different fields \r\n\r\n\r\n -->\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n<head>\r\n<title>Support Center</title>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html;
I either need the page to redirect properly (which works fine on Get, just not Post) or to be able to return an empty JSON string and trigger the AJAX success function. I don't particular care which - I can handle the result either way. I just can't get either option to work. What am I doing wrong?
If you want to return JSON in a #Controller class, then annotate the return type of the method with #ResponseBody.

Dynamic / Changing variable in AJAX get Request

I have a page on a project I'm developing that is attempting to make an ajax request with a specific value assigned by the button's (there are multiple) id tag. This works; the value is successfully passed and an ajax call is triggered on every click.
When I try to make the call again to the same page with a different button the variables are reassigned however the GET request that is sent remains unchanged.
How do I pass a NEW variable (in this case id) passed into the GET request?
function someAJAX(target) {
var trigger = [target.attr('id')];
console.log[trigger];
$.ajax({
// The URL for the request
url: "onyxiaMenus/menuBase.php",
// The data to send (will be converted to a query string)
data: {
//class: target.attr("class"),
tableCall: true,
sort: trigger,
sortOrder: 'DESC',
},
// Whether this is a POST or GET request
type: "GET",
// The type of data we expect back
//The available data types are text, html, xml, json, jsonp, and script.
dataType: "html",
// Code to run if the request succeeds;
// the response is passed to the function
success: function (data) {
console.log("AJAX success!");
$('#prop').replaceWith(data);
}
,
// Code to run if the request fails; the raw request and
// status codes are passed to the function
error: function (xhr, status, errorThrown) {
console.log("Sorry, there was a problem!");
console.log("Error: " + errorThrown);
console.log("Status: " + status);
console.dir(xhr);
}
,
// Code to run regardless of success or failure
complete: function (xhr, status) {
console.log("The request is complete!");
$('#view').prepend(xhr);
}
});
}
$(document).ready(function () {
$(".sort").on( "click", function (e) {
//e.stopPropagation();
//e.preventDefault();
target = $(this);
//console.log(target.attr("class"));
console.log(target.attr("id"));
/* ADD CHILDREN TO ELEMENT*/
if (target.hasClass('asc')) {
target.removeClass('asc')
} else {
target.addClass('asc')
}
/* MANAGE CLASS ADD/REMOVE FOR TARGET AND SIBLINGS */
if (target.hasClass('btn-primary')) {
} else {
target.addClass('btn-primary')
}
someAJAX(target);
target.siblings().removeClass('btn-primary');
})
});
Try to call your ajax like this someAJAX.bind(target)();
Then in function become
function someAJAX() {
$.ajax({
// The URL for the request
url: "onyxiaMenus/menuBase.php",
// The data to send (will be converted to a query string)
data: {
//class: this.attr("class"),
tableCall: true,
sort: this.attr('id'),
sortOrder: 'DESC',
},
// Whether this is a POST or GET request
type: "GET",
// The type of data we expect back
//The available data types are text, html, xml, json, jsonp, and script.
dataType: "html",
// Code to run if the request succeeds;
// the response is passed to the function
success: function (data) {
console.log("AJAX success!");
$('#prop').replaceWith(data);
}
,
// Code to run if the request fails; the raw request and
// status codes are passed to the function
error: function (xhr, status, errorThrown) {
console.log("Sorry, there was a problem!");
console.log("Error: " + errorThrown);
console.log("Status: " + status);
console.dir(xhr);
}
,
// Code to run regardless of success or failure
complete: function (xhr, status) {
console.log("The request is complete!");
$('#view').prepend(xhr);
}
});
}
trigger doesn't seem to be defined anywhere. That's the only data that would be changing between your requests as the other ones are statically coded.
You just need to make sure trigger is defined and changes between the two requests.
Thanks for the input on this problem. I got down to the bottom of my problem. My requests were being handled correctly but dumping the tables was creating syntax errors preventing the appending of new information to my page.
Thanks for the quick replies!
It wall works now.

How to handle ajax errors on response.

I have a single page order form. The user fills our the form, javascript validates everything and if it passes an ajax request will hit the server and charge the customer via Stripe when they click submit.
If the charge is successful, json is returned to the ajax request ({success:true}). The user is then redirected to an success page, or an error is displayed if something happened when charging the card.
I'm trying to handle a (rare) issue where the user's request hits the server, the user is successfully charged, but on response the user receives an error (most likely a timeout error on mobile/unstable connection). How can I prevent a user from being double charged? Below is my ajax request, but maybe I need to rethink my entire infrastructure?
$.ajax({ type : 'POST',
url : '/order',
data : $(':input').serialize(),
timeout : 30000,
dataType : 'json',
success : function (data) {
// redirect user to success page
window.location = '/completed';
},
error: function(xhr,status,error) {
// report the error to user.
} });
Try this..
$.ajaxSetup({
type : 'POST',
url : '/order',
data : $(':input').serialize(),
timeout : 30000,
dataType : 'json',
success : function (data) {
// redirect user to success page
window.location = '/completed';
},
error: function(xhr,status,error) {
if (xhr.status == 408) {//For Timeout
alert("Sorry, Request timeout.!");
window.location.href ="//specify a redirect url//";
}
else {
alert("An error occurred: " + status + "nError: " + error);
}
} });

Cross domain jQuery ajax calls not working

I'm having trouble with this code and I can't seem to get it to work. The typical error that I get back for this call is a "Failed to load resource: the server responded with a status of 401 (Unauthorized) " .
$('#btnZendesk').click(function () {
$.ajax({
url: "https://flatlandsoftware.zendesk.com/api/v2/topics/22505987.json",
type: 'GET',
crossDomain: true,
xhrFields: {
withCredentials: true
},
cache: false,
dataType: 'jsonp',
processData: false,
data: 'get=login',
timeout: 2000,
username: "test#test.com",
password: "test",
success: function (data, textStatus, response) {
alert("success");
},
error: function (data, textStatus, response) {
alert(data);
}
});
Problem is that the resource you are trying to access is protected with Basic Authentication.
You can use beforeSend in jQuery callback to add a HTTP header with the authentication details e.g.:
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Basic XXXXXX");
}
Alternatively you can do it using jQuery ajaxSetup
$.ajaxSetup({
headers: { 'Authorization': "Basic XXXXX" }
});
EDIT
A few links to the mentioned functions
jQuery.ajaxSetup
jQuery.ajax
EDIT 2
The Authorization header is constructed as follows:
Username and password are joined into a string "username:password" and the result string is encoded using Base64
Example:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
I too got this problem and somehow all solutions from internet either failed or were not applicable due to client webservice restrictions (JSONP, XDR, CORS=true)
For this, I added an iframe in my page which resided in the client;s server. So when we post our data to the iframe and the iframe then posts it to the webservice. Hence the cross-domain referencing is eliminated.
We added a 2-way origin check to confirm only authorized page posts data to and from the iframe.
Hope it helps
<iframe style="display:none;" id='receiver' name="receiver" src="https://iframe-address-at-client-server">
</iframe>
//send data to iframe
var hiddenFrame = document.getElementById('receiver').contentWindow;
hiddenFrame.postMessage(JSON.stringify(message), 'https://client-server-url');
//The iframe receives the data using the code:
window.onload = function () {
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
eventer(messageEvent, function (e) {
var origin = e.origin;
//if origin not in pre-defined list, break and return
var messageFromParent = JSON.parse(e.data);
var json = messageFromParent.data;
//send json to web service using AJAX
//return the response back to source
e.source.postMessage(JSON.stringify(aJAXResponse), e.origin);
}, false);
}

Upload file using Jquery form plugin

I am using Jquery form plugin to upload file in Ajax request.File is successfully sent to server but on response browser is asking to save response with following popup
Here is my HTML
<form:form name="newRequestForm" id="newRequestForm" modelAttribute="requestForm" method="POST">
<form:input path="mrnFile" type="file" size="40"/>
</form:form>
JS
// Initializing Jquery form
$(function() {
$('#newRequestForm').ajaxForm();
});
// This function is called on click event of submit button
function submitDataRequest(formAction) {
var options = {
beforeSubmit: showRequest, // pre-submit callback
success: showResponse, // post-submit callback
url: formAction,
dataType: 'json'
};
$('#newRequestForm').ajaxSubmit(options);
}
function showRequest(formData, jqForm, options) {
alert('About to submit: ');
return true;
}
function showResponse(data, statusText, xhr, $form) {
Alert("In response..")
if (!data.actionPassed) {
showErrors(data.errors);
$("#hideOrShowErrors").show();
} else {
showConfirmation(data, confirmationMsg, formName, successFormAction);
}
}
showResponse is never invoked instead browser shows the popup.
I checked through Firebug, the response code is 200 still success callback is not executed.
After reading some similar question I think it has something to do with server response type. So I did following in my spring controller
public ResponseEntity<ResponseDTO> save(#ModelAttribute("dataRequestForm") DataRequestFormDTO dataRequestFormDTO, BindingResult result, SessionStatus status, Model model, HttpServletResponse response) {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<ResponseDTO>(responseDTO, responseHeaders, HttpStatus.CREATED);
}
On both side I have data type as json but still I am getting the popup.Am I making any blunder?
Thanks!
EDIT:
Updated JS
function submitDataRequest(formAction) {
var options = {
beforeSubmit: function(){
alert("Before submit");
}, // pre-submit callback
success: function(){
alert("On success");
}, // post-submit callback
url: formAction
}
$('#newRequestForm').ajaxSubmit(options);
}
Still I get the same popup and success callback is not fired.
Added initBinder in controller
#InitBinder
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws ServletException {
binder.registerCustomEditor(CommonsMultipartFile.class,
new ByteArrayMultipartFileEditor());
}
After adding initBinder I got following error
No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer
This is a common issue with IE and iframe (used by jquery form plugin to upload files with ajax).
I solved in two steps:
1) Server Side: remove headers, send back just the content.
2) Client-Side: do not set the ajax request dataType parameter and on success use the following code to extract json:
success: function(data)
{
try{
jsonData = jQuery.parseJSON(data);
// continue process with json encoded data
}
catch(e)
{
// handle parsing error
}
}

Categories

Resources