Jquery Ajax requests not working on IE 10 (due to cache) - c#

I would like to begin with this. I am fed up with IE. I have the code below:
$(function () {
$("#cal").on('click', "#forward", function () {
$.ajax({
url: "Home/Calendar?target=forward",
type: "GET",
success: function (result) {
$("#cal").html(result);
}
});
});
});
$(function () {
$("#cal").on('click', "#backwards", function () {
$.ajax({
url: "Home/Calendar?target=backwards",
type: "GET",
success: function (result) {
$("#cal").html(result);
}
});
});
});
It is an ajax call to a controller action in an C# MVC application. It just goes back and forth a calendar's months replacing the html. Now I know that you need to reattach the event due to the html() call and that is why I use on() with JQuery 1.7. I have used delegate() as well. In FF, Chrome it works as intended. In IE 10 it does not. I am at a loss. I knew that IE had issues with delegate in IE8 and with JQuery < 1.5 but this is not the case.
Does anyone know how to solve this?

I am answering the question just for future reference for other people. It seems that IE is caching AJAX requests for some reason I am unable to comprehend.
I noticed using the (surprisingly good) developer tools IE 10 provides that I was getting a 304 not modified response to my AJAX requests. This was not the case in Firefox or Chrome (200 was the response).
I added the cache: false option to my AXAJ JQuery functions and now it works as intended.
IE never seizes to amaze me.

Brief addition, given what (little) I understand on the subject. Apparently, the XmlHttpRequest spec says that XHR GET commands can behave just like a standard web page retrieval (e.g. clicking on a regular old link), and therefore XHR GET commands can be cached. The IE team has chosen to adhere to this spec, while the other browser makers have not. While I can see some logic in this approach, I think those of us who work with XHR requests every day would emphatically say that we would prefer caching to be off by default, rather than on. (-;

I ran into this a long long long time ago with IE... now I always make it a point now to write my ajax calls with a random trailing key/value pair.
I also add cache: false though I have found by itself it doesn't always do what it should (well, maybe its just IE not doing what it should)
This is how I set them up...
$('#trigger').submit( function(e){
e.preventDefault();
var randnum = Math.floor(Math.random()*1001); //magic starts here
$.ajax({
type: "POST",
url: "folder/file.php",
cache: false,
data: "random=" + randnum, //pure magic
success: function(){
// do stuff here
}
});
});

Got this issue too. It turns out that all of the fixes above will not work if the POST response has cache-control: max-age. The 1st request will fetch the data but after that all requests (even if you add a random attribute) will be 304'd.
In this case IE will not even ask the server if the content changed, it just assumes that if it has a max-age then there's no point in doing a request.
Moreover XHR specs say that 304's shouldn't pass any data so basically you get an empty response for a POST (just on IE 9 and 10).

Related

which cookies/headers should I set?

I should get a protected page from external site, if I call it directly, I get an error:
Bad Request
Postman:
But if I call a login page with valid credentials via Postman:
and then recall THE SAME resource page from the same Postman I got the protected page!:
I have to get the same page on website. I try to implement it by the following way:
var loginXml = "<Request><MsgType>Authenticate</MsgType><SubMsgType>Login</SubMsgType><UserID>my_login</UserID><passwordNotEncrypted>my_password</passwordNotEncrypted></Request>";
$.ajax(
{
url: 'https://address/browserservices.aspx/login',
type: 'POST',
contentType: 'text/xml',
datatype: 'text',
//xhrFields: {
// withCredentials: true
//},
//crossDomain: true,
data: loginXml,
success: function (output, status, xhr) {
alert(xhr.getResponseHeader("Set-Cookie"));
$.ajax({
url: "https://address/RemoteSupport.aspx?id=GUID&pltFrmType=Android&agentversion=13.46",
type: 'GET',
xhrFields: { withCredentials: true },
//crossDomain: true,
success: function (x) { },
error: function (xhr, textStatus) { alert(xhr.status); }
});
},
})
but I get Bad Request again.
Which headers/cookies should I pass to page to open protected page, like it's in Postman?
ADDED 28/01/19
Postman "Cookie" tab after success login request (fail login request has the same):
and "Headers" tab:
as I see, all access-control-allow header are available. What should I pass via ajax?
Based on the information that you have supplied there are two likely scenarios.
Firstly, the cookie that is set by the external site is HttpOnly. This is easy enough to check in Postman, by clicking on the the Cookies tab.
The second option is a little more complex, but the external server has to set the Access Control headers correctly. Again there is a Headers tab to view these. More info on cross domain ajax and headers in this question: Why is jquery's .ajax() method not sending my session cookie?
Finally worth noting, your browser will automatically add a header to indicate that it is an ajax request. You could try adding the X-Requested-With: XMLHttpRequest header in Postman and seeing how it differs from your examples. The external server may well be configured to respond differently to ajax requests than to browser or server-server api requests.
Update
Your Postman update shows that both of those scenarios are true. Unfortunately this means that you cannot achieve your desired result with JavaScript. HttpOnly = true means that the browser will never allow the script on your page to access the cookie.
At this point your best bet is probably to write a little proxy method on your own site that makes the request server to server and then returns the result to your JavaScript code. This should bypass all the above issues albeit you need to make 2 requests instead of 1 for the data.
Take a look at this answer for some code
Struggling trying to get cookie out of response with HttpClient in .net 4.5

knockout server call doesn't run at all

Edit: I thought this function was calling the wrong api, however after commenting it out I realize that the function does not work at all. The page was generating the call itself.
So why doesn't this function send a call to the controller at all when the same function without a parameter, and wrapped in Ko.computed works ok?
I am using Knockoutjs and ASP.net MVC 5 to make a webpage. There are two calls to the server passing a parameter one works well, the other never works.
I am using this exercise as a base for my own project. using-web-api-with-entity-framework/part-6
I have a single ajax helper from the exercise
function ajaxHelper(uri, method, data) {
self.error(''); // Clear error message
return $.ajax({
type: method,
url: uri,
dataType: 'json',
contentType: 'application/json',
data: data ? JSON.stringify(data) : null
}).fail(function (jqXHR, textStatus, errorThrown) {
self.error(errorThrown);
});
}
This function below works and sends GET /api/Guests/20 using the API of GET api/Guests/{id} returning back data
self.getGuestDetail = function(item) {
ajaxHelper(guestUri + item.GuestID, "GET").done(function(data) {
self.detail(data);
});
Yet this function, which is pretty much identical doesn't return any data, basically the same server call is being sent differently.
The api it wants is GET api/RoomBooking?DateFrom={DateFrom} (server side datefrom at this stage is a string)
self.RoomList = ko.observableArray(); //an array that will hold each room when foreached ko.computed(
self.ShowFreeRoomsFunction = function (item) {
ajaxHelper(roombookingUri + item.BookingFrom, "GET").done(function (data) {
self.RoomList(data);
});
I have been looking at this all day, and am totally lost. I have replaced the Datefrom with just simple strings to get something to pass, but it seems as soon as I try to pass a parameter, the method never sees it.
When I don't pass a parameter and wrap in ko.computed the method works returning data.
Here is the same call working by wrapping it in a ko.computed function. It sends off the GET /api/RoomBooking/ api which is what I want
self.RoomList = ko.observableArray(); //an array that will hold each room when foreached ko.computed(
self.ShowFreeRoomsFunction = ko.computed(function () {
ajaxHelper(roombookingUri, "GET").done(function (data) {
self.RoomList(data);
});
});
Close to Success achieved the url has to be http://localhost:50524/api/RoomBooking/?textA=asdfghjkl with the ? in it. Now all that needs fixing is how to pass the variable to replace asdghjkl and then move dates.
If I manually enter the url into the browser I can see it moving across in fiddler and it returns data as a json file.
But if I try to do it through the program it never shows in fiddler nor runs.
Fiddler result:
Result Protocol Host URL Body Caching Content-Type Process Comments
Custom 51 200 HTTP localhost:50524 /api/RoomBooking/?textA=asdfghjkl
117 no-cache; Expires: -1 application/json; charset=utf-8
iexplore:10040
What might I be doing wrong in my Get call that stops it ever showing even when hard coded in like this?
self.RoomList = ko.observableArray(); //an array that will hold each room when foreach
self.ShowFreeRoomsFunction = function (item) {
ajaxHelper("/api/RoomBooking/?textA=asdfghj", "GET").done(function (data) {
self.RoomList(data);
});
};
Thanks guys.

asp.net api service.svc query length problems

Hello I got a service that is made for sending html mails, it will be called from a method "SendMail(data) about 1500 characters.
I access the service though JQuery with AJAX call and JSON:
var data = encodeURIComponent(JSON.stringify(dataArray));
$.ajax({
type: "GET",
url: "http://localhost:53334/Service.svc/SendMail?data=" + data,
contentType: 'application/json; charset=utf-8',
dataType: "json",
success: function () {
alert("Reklamationen er blevet sendt!");
},
error: function (err) {
alert("Kunne ikke sende reklamation! Der opstod en fejl.");
}
});
I got alot of fields and if I fill everything out it gives a 404 not found response but then if I leave some random fields empty it gets to the API and executes the method it should? So I think its about the data size. I have tried many settings in webconfig but i havent managed to find a solution.
I hope there will be someone who can help me.
You should really be using POST as indicated by Tikkes. Semantically you aren't requesting a resource from the server, so GET doesn't make sense. Also, as noted here there is a maximum length that is enforced for Urls which is what GET uses to pass params(as you can see in your code as well). POST on the other hand uses the request body to send its data. Also, as noted here POST and GET sizes are usually configurable on the server, but POST is generally much larger(2KB vs 10MB defaults) as stated in one of the answers. Hope this helps.

ajax post does not send data

I have this ajax-post:
$.ajax({
url: Config.Proxy + "ContentPages.aspx?t=save",
type: "POST",
contentType: "application/x-www-form-urlencoded",
data: {
content: content,
id: currentPageId,
active: "true",
subject: $('#txtSubject').val(),
webid: webid
},
success: function (data, status) {
// do something
},
error: function (xhr, desc, err) {
// Do something
}
});
I do a post to an .NET page, so I could use the debug mode to check if the data is send correctly.
I use the same code as above for a different page (other url, other data).
When I run the application and save the data I don't come in the debug mode. When I use the same code for the other page, it works fine.
I tried to compare both codes, but they are the same. I have removed some data-items, but it still does not work.
Why? Can anyone give me a hint?
Thanks
EDIT *
I know why this is happening: CKEditor. As soon as I set the variable "content" to the content of the CKEditor and use the post-call, the debug-mode is not called anymore. Also the form-keys in the code-behind are 0.
The question now is how to fix this?
Like said in the edit of my original post: Problem was caused by the content of the CKEditor. I think HTML is not parser/loaded/call-it-what-you-want in an AJAX-post.
So, with a little help (and without posting code-behind, that had nothing to do with the problem) I figured it out:
var content = escape(CKEDITOR.instances.editor1.getData());
Put the variable "content" in the data-section of the post and voila! It works like a charm.
On the receiving .NET page in code behind, decode the value:
(HttpUtility.UrlDecode(Request.Form.Get("content").NullSafeString())
Thanks anyway

Progress Bar while sending ByteArray to Server through Action Method in MVC 3

I have a byte-array that i upload to the server through action method from javascript (MVC3):
$.ajax({
url: '#Url.Action("Upload")',
type: 'POST',
contentType: 'application/x-amf',
processData: false,
data: ByteArrayData,
success: function (result) {
alert(result);
}
});
I was wondering what is the easiest way to make a percentage progress bar while the bytes are getting sent to the server?
Easiest way would be to Mask the content using javascript or show Javascript progress bar on view, until you get the response back from Server.
My initial (and boring) response is that this would be hard to do, but I'm not wise enough with the HTTP post request to completely be sure if it is or isn't possible. Essentially though you'd have to either know:
Size of posted data
Upload speed
OR
Size of posted data
Data sent each interval (if such a thing even exists?)
I'm not sure you can access either of these combinations with JavaScript. You'd probably need to use some sort of flash uploader for this.

Categories

Resources