So, I've used Backbone.js to write a messaging system. It works fine in Chrome and FF but IE9 has issues with a particular fetch call that kills it. (I'm working in MVC3).
I have a poll that checks for new messages coming in, which sends the date to the server. The poll is called with this method:
DoMessageFetch = function() {
var now = new Date().toUTCString();
Chat.mymessages.fetch({
cache: false,
data: {
Now: now
},
success: function (response) {
// if there are messages ...
// for each message, open a chat window
if (Chat.mymessages.length > 0) {
for (var i = 0; i < Chat.mymessages.length; i++) {
var useridto = Chat.mymessages.at(i).get("UserId");
var name = Chat.mymessages.at(i).get("ScreenName");
// a chat-window with this useridto is NOT on the page
if (!($('#chat-window-' + useridto).is(':visible'))) {
Chat.doChatMessageFetch(name, useridto, null); // this constructs a Backbone view
}
}
}
},
error: function () { console.log('ERROR: fetching general poll messages failed.'); }
});
Chat.mymessages.reset();
}
In IE9 the Now param is null when I watch breakpoints in my Controller. This means the request follows the wrong code path on the server...
I don't understand where my Now parameter went in IE. Can any one help?
This problem is due to the different behaviour of
new Date().toUTCString()
between IE , Google Chrome and Firefox.
For example the result in Chrome is :
"Thu, 20 Sep 2012 20:19:15 GMT"
while in IE you will get
"Thu, 20 Sep 2012 20:19:15 UTC"
MVC3 ModelBinder will ignore IE Format and leave your Now parameter null.The solution to this problem is to replace
new Date().toUTCString()
with
new Date().toJSON()
The only thing to note with this solution is that it will not work by default on IE7 due to the lack of the toJSON() function but this problem can be solved using Douglas Crockford json2.js library which is also recommended when using Backbone.js
Related
I'm using a Web App (which is really big) so there are some parts of the application that I really don't know how they work.
I am a front end developer and I'm consuming a REST API implemented with .NET Web Api (as far as I know)
The request is simple - I use kendo Datasource to get the data from the server like this
var kendoDataSource = new kendo.data.DataSource({
// fake transport with local data
transport: {
read: function(options) {
// set results
options.success(lookupValues);
}
},
schema: {
parse: function (response) {
// sort case insensitive by name
response.sort(function (a, b) {
return (a.Name.toLowerCase() > b.Name.toLowerCase()) ? 1 : (a.Name.toLowerCase() < b.Name.toLowerCase()) ? -1 : 0;
});
return response;
}
},
// set the page size
pageSize: 25
});
and the request for the data
$http({ method: 'GET', url: 'REST/SystemDataSet/' + id + '/Values' }).success(function (response) {
// store data
lookupValues = response;
kendoDataSource.read();
// do some logic here
}).error(function(error) {
// logic
});
I do this in this way because there is some extra logic that manipulates the data.
This request in Chrome takes like 32 ms while it takes almost 9 seconds in IE.
The data retrieved is the same (you can see the Size of response), which is an array of JSon objects (Very simple)
I don't know exactly if there is a cache mechanism in the backend, but it shouldn't matter because I'm able to reproduce it like this every time (fast in Chrome, really really slow on IE)
Any ideas of what could be causing this behaviour ? As I understand, if there is a cache or something, it should be the same for every browser, so this should be happening on both and not only on IE - the backend is agnostic of the browser.
Here is some extra information I have from another request to check the distribution of time in the first IE request
As you can see, the biggest part is the "Request", which is the Time taken to send the request and receive the first response from the server.
Thanks in Advance
The problem is probably Windows Authentication turned on for the folder you are calling the ajax from...
Same principle applies here ...
http://docs.telerik.com/kendo-ui/web/upload/troubleshooting
Problem: Async uploads randomly fail when using IE10/11 with Windows Authentication
The upload either freezes indefinitely or times out if a 401 challenge is received on the HTTP POST.
Solution
For IE10 see KB2980019
No official fix for IE 11 as of November 6, 2014. See bug ID 819941
my web site is made using Ext JS 4.1 framework and ASP .Net MVC v3. When new frame is rendered there are 19 separate AJAX requests for retrieving data in JSON-format. All requests are familiar and made by Ext.Ajax.request(). Example:
Ext.Ajax.request({
url: getOrderLink,
method: "GET",
params: { recId: orderRecId },
headers: {
'Accept': 'application/json'
},
success: function (response) {
var order = Ext.decode(response.responseText);
...
}
});
In some cases there are errors in ext-all.js in
onStateChange : function(request) {
if (request.xhr.readyState == 4) {
this.clearTimeout(request);
this.onComplete(request);
this.cleanup(request);
}
},
where request has no property xhr so that request.xhr.readyState throws exception "Cannot read property 'readState' of undefined".
This errors appear not for all requests and don't effect site work(responses are retrieved successfully). Some times this errors don't appear at all. Timeout for all requests is set to 30s by default and they take about 1.5-2 seconds each.
I am using Google Chrome 21.
Could you please give me some idea why it's happening.
The problem seems to occur if and only if you have a breakpoint or a "debugger;" line in anything related to AJAX. For me it happened in Chrome, haven't tried other browsers yet.
In my case it happened when I had set a breakpoint in a load event handler for a store like code example below.
But the error occurrs if you set a breakpoint inside the Ext onStateChange function in the framework itself as well.
If disabling your breakpoints and debugger; calls removes the error you can safely ignore it!
There is a similar thread on ExtJS forums. Sencha might add a fix.
Ext.define('MyApp.controller.MyController', {
extend: 'Ext.app.Controller',
stores: ['Projects'],
init: function () {
this.getProjectsStore().addListener(
"load",
this.onProjectsStoreLoaded,
this
);
},
onProjectsStoreLoaded: function () {
console.log('MyController: onProjectsStoreLoaded');
debugger; // <- this causes the errors to appear in the console
SomeOtherThingsIWantedToDebug();
}
}
I have a web application that must work with IE7 (yeah i know..) where the frontend is entirely made with ExtJS4, and theres a servlet used to download files. To download a file i send some parameters so i cant simply use location.href. it must be a POST.
So far it works, but when an exception is thrown in the servlet i dont know how to handle it to show the user some alert box or some message without redirecting to another page.
In my webapp im also using DWR and im aware of the openInDownload() function, but it triggers a security warning in IE.
So, (finally!) the question is
Using this code:
post = function (url, params) {
var tempForm=document.createElement("form");
tempForm.action=url;
tempForm.method="POST";
tempForm.style.display="none";
for(var x in params) {
// ...snip boring stuff to add params
}
document.body.appendChild(tempForm);
tempForm.submit();
return tempForm;
}
is it possible to stay in the same page after submitting ?
or with this other one:
Ext.Ajax.request({
url: './descargaArchivoNivs',
method: 'POST',
autoAbort: true,
params: {
nivs: jsonData
},
success: function(response){
// HERE!!
// i know this is wrong
document.write('data:text/plain,' + response.responseText );
/* this looked promising but a warning pops up
var newwindow = window.open();
newwindow.document.open();
newwindow.document.write('data:text/plain, ' + response.responseText );
newwindow.document.close();*/
},
failure: function(resp){
alert('There was an error');
}
});
is it possible to open the file download dialog // HERE!! with the response content??
or is there some other way to open the file download dialog on success, and on failure show a friendly message without losing the users input (the params of the POST) ?
(sorry if this post was too long)
I'm having the classic IE-caches-everything-in-Ajax issue. I have a bit of data that refreshes every minute.
Having researched the forums the solutions boil down to these options (http://stackoverflow.com/questions/5997857/grails-best-way-to-send-cache-headers-with-every-ajax-call):
add a cache-busting token to the query string (like ?time=[timestamp])
send a HTTP response header that specifically forbids IE to cache the request
use an ajax POST instead of a GET
Unfortunately the obvious querysting or "cache: false" setting will not work for me as the updated data file is hosted on Akamai Netstorage and cannot accept querystrings. I don't want to use POST either.
What I want to do is try send an HTTP response header that specifically forbids IE to cache the request or if anyone else knows another cache busting solution??
Does anyone know how this might be done? Any help would be much appreciated.
Here is my code:
(function ($) {
var timer = 0;
var Browser = {
Version: function () {
var version = 999;
if (navigator.appVersion.indexOf("MSIE") != -1) version = parseFloat(navigator.appVersion.split("MSIE")[1]);
return version;
}
}
$.fn.serviceboard = function (options) {
var settings = { "refresh": 60};
return this.each(function () {
if (options) $.extend(settings, options);
var obj = $(this);
GetLatesData(obj, settings.refresh);
if (settings.refresh > 9 && Browser.Version() > 6) {
timer = setInterval(function () { GetLatestData(obj, settings.refresh) }, settings.refresh * 1000);
}
});
};
function GetLatestData(obj, refresh) {
var _url = "/path/updated-data.htm";
$.ajax({
url: _url,
dataType: "html",
complete: function () {},
success: function (data) {
obj.empty().append(data);
}
}
});
}
})(jQuery);
Add a random number to the GET request so that IE will not identify it as "the same" in its cache. This number could be a timestamp:
new Date().getTime()
EDIT perhaps make the requested url:
var _url = "/path/updated-data.htm?" + new Date().getTime()
This shouldn't cause any errors I believe.
EDIT2 Sorry I just read your post a bit better and saw that this is not an option for you.
You say "is hosted on Akamai and cannot accept querystrings" but why not?
I've never heard of a page that won't accept an additional: "?blabla", even when it's html.
This was driving me crazy. I tried many cache busting techniques and setting cache headers. So many of these either did not work or were wild goose chases. The only solution I found which tested to work correctly was setting:
Header Pragma: no-cache
I hope it saves others with IE headaches.
I am using jQuery ajax to load data into a jQuery tab. It works fine in Chrome and FireFox. In IE8 the data is sometimes not loaded. If I clear cache or reload the page it apparently works fine.
As far as I can tell it fails after shutting down IE and then starting it up again some time later. It has failed within hours, but succeeds if the delay is only minutes. At least that is what I think the failure mode is, I have not rigorously determined a magic time.
ETA: It works if I clear the cache or refresh the page.
I have put a superfluous time parameter in the post data, and set cache:false in the ajax call.
The data is not cached since if I change the expected data it will fill it in properly.
Another update:
A missing piece of data. This is a Facebook app. That turns out to be crucial.
I sniffed both the working and not working sessions with Wireshark. It turns out the difference is that the working session submits the Facebook cookies and the not working one doesn't.
So the question is now how to force the ajax call to include cookies. The descriptions I have found about the ajax call is that it includes cookies. Is the behaviour I am seeing a bug?
ETA:
The javascript:
$.ajaxSetup
(
{
// Disable caching of AJAX responses
cache: false
}
);
$(document).ready
(
function()
{
$('#shopTabs').tabs();
thing.create();
thing.editPicture();
$('#shopTabs').bind
(
'tabsselect',
function(event, ui)
{
thing.setReload(ui.index);
thing.setActive(ui.index);
}
);
}
);
// Must be global for Java to call
function reload()
{
thing.create();
thing.editPicture();
}
var thing =
{
reload : 0,
active : 0,
noOp : function()
{
},
create : function()
{
date = new Date();
$('#shopTabs1').load('create.php', {time : date.getTime()}, thing.linkform);
},
editPicture : function()
{
date = new Date();
$('#shopTabs2').load('editPicture.php', {time : date.getTime()}, thing.noOp);
},
linkform : function()
{
$('#upload').ajaxForm({target : '#shopTabs1'});
},
setReload : function
(
index
)
{
this.reload = this.reloadList[index];
},
setActive : function
(
index
)
{
this.active = this.activeList[index];
},
load : function
(
php,
args,
loadFn
)
{
var settings =
{
type : "POST",
cache : false,
url : php,
data : args,
context : this,
success : function (data)
{
$(this.active).html(data);
loadFn();
}
}
$.ajax(settings);
}
};
thing.activeList = ['#ui-tabs-1', '#shopTabs1', '#shopTabs2'];
thing.reloadList = [thing.noOp, thing.create, thing.editPicture];
In your thing.create function, add a changing query parameter, current date is good, or use a random number.
$('#shopTabs1').load('create.php?r='+escape(new Date().toString()), {time : date.getTime()}, thing.linkform);
or
$('#shopTabs1').load('create.php?r='+new Date().valueOf(), {time : date.getTime()}, thing.linkform);
same with your editPicture.
That will prevent IE from caching, as mentioned by Omu's answer
It turns out the problem was that IE officially expects a P3P header to load an iframe from a third third party site. Facebook implements apps using iframes from the app provider.
IE does not consistently fail if there is no P3P header.