I am working on extjs framework..
i have an application running on extjs..
whenever i open the application in the browser...i see the following
warnings in my console...
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/
can you guys tell me how to remove it..
when i click the warning it takes to ext-all-debug-w-comments.js file
and points to the following part of code...
try {
xhr.open('GET', noCacheUrl, false);
xhr.send(null);
} catch (e) {
isCrossOriginRestricted = true;
}
can you guys tell me how to prevent it from happening...
providing my code below in that file
/**
* Load a script file, supports both asynchronous and synchronous approaches
* #private
*/
loadScriptFile: function(url, onLoad, onError, scope, synchronous) {
if (isFileLoaded[url]) {
return Loader;
}
var config = Loader.getConfig(),
noCacheUrl = url + (config.disableCaching ? ('?' + config.disableCachingParam + '=' + Ext.Date.now()) : ''),
isCrossOriginRestricted = false,
xhr, status, onScriptError,
debugSourceURL = "";
scope = scope || Loader;
Loader.isLoading = true;
if (!synchronous) {
onScriptError = function() {
};
scriptElements[url] = Loader.injectScriptElement(noCacheUrl, onLoad, onScriptError, scope);
} else {
if (typeof XMLHttpRequest != 'undefined') {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
try {
xhr.open('GET', noCacheUrl, false);
xhr.send(null);
} catch (e) {
isCrossOriginRestricted = true;
}
status = (xhr.status === 1223) ? 204 :
(xhr.status === 0 && (self.location || {}).protocol == 'file:') ? 200 : xhr.status;
isCrossOriginRestricted = isCrossOriginRestricted || (status === 0);
if (isCrossOriginRestricted
) {
}
else if ((status >= 200 && status < 300) || (status === 304)
) {
// Debugger friendly, file names are still shown even though they're eval'ed code
// Breakpoints work on both Firebug and Chrome's Web Inspector
if (!Ext.isIE) {
debugSourceURL = "\n//# sourceURL=" + url;
}
Ext.globalEval(xhr.responseText + debugSourceURL);
onLoad.call(scope);
}
else {
}
// Prevent potential IE memory leak
xhr = null;
}
},
This warning is only showing in Chrome in the development environment of ExtJs. Once the application is built with sencha cmd, the warning doesn't show anymore. As #Evan pointed out the warning looks benign, and you should not have to worry about it.
The fact that there is a warning should not be an issue, since it will never show in a deployed application. If you do not yet use sencha cmd, it is definitely worth to integrate it in your development cycle.
I know it is not a direct answer to the question. Myself, I wonder if it is possible to get rid of this warning at all.
Related
In my website I am currently trying to write code to turn a link into a formatted attachment .
I am trying to write code to detect if the file exists
function doesFileExist(urlToFile) {
var xhr = new XMLHttpRequest();
xhr.open('HEAD', urlToFile, false);
if (xhr.status == "404") {
return false;
} else {
return true;
}
}
alert(doesFileExist("http://hexbugman213.net/favicon.png"));
However, I noticed a problem. When the website has a 404 handler like .htaccess, and I try to test it with the file, it sees that the website didn't return a 404, and therefore still says it exists.
function doesFileExist(urlToFile) {
var xhr = new XMLHttpRequest();
xhr.open('HEAD', urlToFile, false);
if (xhr.status == "404") {
return false;
} else {
return true;
}
}
alert(doesFileExist("http://hexbugman213.net/thisfiledoesntexist.mp3"));
Is there any way I can account for this and have it return "false" when the file doesn't exist even if there's a 404 handler?
You need to call the send() function on the XMLHttpRequest to make it actually make the request. See: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
Also, you may run into cross origin issues depending on exactly what URL you're trying to retrieve and where you're hosting the page from. Mozilla has some documentation on the subject if you're not familiar with it: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Here is an improved version of your JavaScript that checks for exceptions and calls the send() function.
function doesFileExist(urlToFile) {
try {
var xhr = new XMLHttpRequest();
xhr.open('HEAD', urlToFile, false);
xhr.send();
alert(xhr.status)
if (xhr.status !== 200) {
return false;
} else {
return true;
}
} catch (e) {
alert(e);
return false;
}
}
alert(doesFileExist("https://server.test-cors.org/server?enable=true&status=200&credentials=false"));
alert(doesFileExist("https://server.test-cors.org/server?enable=true&status=404&credentials=false"));
alert(doesFileExist("https://www.google.com/"));
alert(doesFileExist("http://hexbugman213.net/thisfiledoesntexist.mp3"));
The host: https://www.test-cors.org/ in the example is useful for testing CORS.
I am writing a JavaScript program which requires significant usage of XHR methods. I am using the asynchronous style. This is the core of what I have.
global = {};
global.xhr = {};
global.xhr.requestQueue = [];
global.xhr.responseQueue = [];
xhr = new XMLHttpRequest();
xhr.first = true;
xhr.onreadystatechange = function() {
//console.log(this.readyState);
if(this.readyState == 4) {
if(this.first) {
this.first = false;
global.carouselItems = parseInt(this.responseText);
global.onSlideCountReceived();
} else {
global.xhr.responseQueue.push({status: xhr.status, responseText: xhr.responseText});
if(global.xhr.requestQueue.length > 0) {
xhr.open("GET", global.xhr.requestQueue[0]);
global.xhr.requestQueue.shift();
}
}
}
if(xhr.readyState == 1) {
xhr.send();
}
}
//Code which adds a bunch of items to global.xhr.requestQueue
xhr.open("GET","assets/carousel/items.php");
But when I run this, the Chrome Dev console prints a bunch of errors like the following.
Uncaught InvalidStateError: Failed to execute 'send' on 'XMLHttpRequest': The object's state must be OPENED.
This is despite the only call to xhr.send() being in the snippet above, wrapped in its if statement. This is confusing to me, because the way I see it suggests that I make a call to xhr.send() when xhr.readyState is 1, equivalent to XMLHttpRequest.OPENED and yet I get a complaint about this not being the case.
By the way, the requests all complete successfully, and global.xhr.responseQueue is populated with expected response info. These are all intra-domain requests.
is there a way to detect resources on the page with response 404?
Also why the browser api- performance.getEntriesByType("resource") doesn't include the failed resources?
Well, with this function :
function UrlExists(url) {
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
if (http.status == 404) {
// do something
}
}
And you pass the URL of your resource. but it's not the best solution ever to check this. Let's say it's the simplest :)
EDIT :
After you can also do it for every kind of resources (CSS, Images, ...), a function like this one :
var styleSheetExists = function(name) {
for (var i in document.styleSheets) {
if (typeof document.styleSheets[i] == "object") {
link = document.styleSheets[i].href;
if (link === null) {
continue;
}
if (link.indexOf(name, link.length - name.length) !== -1) {
return true;
}
}
}
return false;
}
That you can use like :
$(document).ready(function() {
console.log(styleSheetExists('jquery-ui.css'));
console.log(styleSheetExists('doesnotexist.css'));
});
(Source of the function : How to check for 403 and 404 errors when changing the url of a resource?)
and by checking every kind of resource, you can assure that there is or not a 404 status about them.
I have the following code in a web worker:
self.addEventListener('message', function(e){
try {
var xhr=new XMLHttpRequest()
for(var i = 0; i < e.data.urls.length;i++){
xhr.open('GET', e.data.urls[i], true);
xhr.setRequestHeader('Accept', 'application/json');
xhr.send(null);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200 || xhr.status == 304 || xhr.status ==0) {
postMessage(xhr.responseText);
} else {
postMessage(xhr.status + xhr.responseText);
throw xhr.status + xhr.responseText;
}
}
};
}
} catch (e) {
postMessage("ERROR:"+e.message);
}
}, false);
e.data.urls contains 16 requests which are handled on the UI thread like this:
var replies = 0;
worker.addEventListener('message', function(e){
replies += 1;
});
Only 10 requests complete, is this because the UI thread has stopped before all the requests have returned or is there something else I am missing?
What is happening here is that your xhr variable gets overwritten in the loop. Due to the nature of XMLHttpRequest, that is, it is asynchronous by default, after the xhr.send(); line execution doesn't wait so for enters the next loop and the xhr.[...] lines operate on the xhr object set up and fired in the previous loop. Depending on whether the previous loop's request has returned (and thus the state change handler executed) or not (which is quite unpredictible) you overwrite either a 'live' or a 'finshed' xhr object. Those that get overwritten before they are finished are lost.
You should make sure you do not overwrite. Do not operate on the same XMLHttpRequest object but instantiate a new for each request.
I moved the definition of the handler function outside the loop. There's no need to redefine it in each loop. It is called in the context of the XMLHttpRequest instance it is assigned to so this points to the instance.
Also, I swapped the xhr.send() and the xhr.onreadystatechange = ... lines. A state change event handler should be assigned before the request is sent (there are several events fired right from the starting of the send) and althought unlikely, a request may even return with a ready state 4 before the line that adds the event handler is executed in the code.
self.addEventListener('message', function(e){
var xhrs = [];
function handler() {
if (this.readyState == 4) {
if (this.status == 200 || this.status == 304 || this.status ==0) {
postMessage(this.responseText);
} else {
postMessage(this.status + this.responseText);
throw this.status + this.responseText;
}
}
};
for(var i = 0; i < e.data.urls.length;i++) {
xhrs[i] = new XMLHttpRequest();
xhrs[i].open('GET', e.data.urls[i], true);
xhrs[i].setRequestHeader('Accept', 'application/json');
xhrs[i].onreadystatechange = handler;
xhrs[i].send(null);
}
}, false);
Your example is similar to this firefox example except for the loop inside the worker making multiple ajax requests. I'd be curious to know what is causing the failure. You might be hitting a limit on the number of concurrent ajax connections a single worker can process.
Could you try moving the url for loop to the main gui thread:
for(var i = 0; i < urls.length; i++){
worker.postMessage(urls[i]);
}
and change your worker to just do a single ajax call at a time?
self.addEventListener('message', function(e){
try {
var xhr=new XMLHttpRequest()
xhr.open('GET', e.data, true);
xhr.setRequestHeader('Accept', 'application/json');
xhr.send(null);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200 || xhr.status == 304 || xhr.status ==0) {
postMessage(xhr.responseText);
} else {
postMessage(xhr.status + xhr.responseText);
throw xhr.status + xhr.responseText;
}
}
};
} catch (e) {
postMessage("ERROR:"+e.message);
}
}, false);
and see if that works?
The mozilla example has some error handlers that might reveal the problem. You might try adding in the main GUI thread:
worker.onerror = function(error) {
dump("Worker error: " + error.message + "\n");
throw error;
};
and inside the worker:
function errorReceiver(event) {
throw event.data;
}
Does anyone know how to make ajax request function that works cross-browser WITHOUT using a javascript framework like jQuery, etc.?
The XMLHttpRequest object isn't actually all that complicated to use. To be broadly compatible, you have to play a bit of a game to create the object, but after that it's fairly straightforward for simple operations.
Microsoft has examples on the MSDN page for XMLHttpRequest, including a function for creating the object in a cross-browser way that supports early versions of IE. Here's their example:
function getXMLHttpRequest()
{
if (window.XMLHttpRequest) {
return new window.XMLHttpRequest;
}
else {
try {
return new ActiveXObject("MSXML2.XMLHTTP.3.0");
}
catch(ex) {
return null;
}
}
}
function handler()
{
if (oReq.readyState == 4 /* complete */) {
if (oReq.status == 200) {
alert(oReq.responseText);
}
}
}
var oReq = getXMLHttpRequest();
if (oReq != null) {
oReq.open("GET", "http://localhost/test.xml", true);
oReq.onreadystatechange = handler;
oReq.send();
}
else {
window.alert("AJAX (XMLHTTP) not supported.");
}
I'm not suggesting the above exemplifies best practices (Microsoft seems to have their MSDN examples largely written by very, very inexperienced engineers), but it gives you a starting point. For instance, the above requires that the response status be 200 for success, where of course the HTTP specification is clear that anything the 200 <= n <= 299 range is "success".
i often use this method for sending and receiving only json in modern browsers (no old-ie's)
function aj(method, url, data, cb){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = readystatechange;
xhr.open(method, url);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(data && JSON.stringify(data));
function readystatechange(){
if(this.readyState === this.DONE) {
switch(this.status){
case 200:
if(this.getResponseHeader('Content-Type').split(';')[0] !== 'application/json'){
return cb("unexpected Content-Type: '" + this.getResponseHeader('Content-Type') + "'", null);
}
return cb(null, JSON.parse(this.response));
case 401:
location.href = '/authentication/login';
return;
default:
return cb("unexpected status: " + this.status + "", null);
}
}
}//readystatechange
}