I have been searching and have found some similar questions about this problem but thing still doesn't work for me at all.
Here is my function :
function ajaxRequest(url, type, datatype, contenttype, data, displayLoadingImg){
var result="";
displayLoadingImg = (typeof displayLoadingImg === "undefined") ? 0 : displayLoadingImg;
if(displayLoadingImg == 1){
$("#loadingImgAging").css("display","block");
}
$.ajax({
url:url,
type:type,
dataType:datatype,
contentType: contenttype,
data : JSON.stringify(data),
success:function(res){
result = res;
if(displayLoadingImg == 1){
$("#loadingImgAging").css("display","none");
}
},
error:function(res){
result="";
},
async : false
});
return result;
}
How I call it :
setTimeout(ajaxRequest(url,"GET","json","application/json",0,1), 500);
I've tried using beforeSend() but it did not work neither.
Note : If I delete async : false or put it to true, I'll get error Cross-Origin Request Blocked.... in my browser console.
My guess is you cannot do an ajax request with local files. There are ways to do this, but i prefer these two methods
Create a simple server
I usually use python for creating a simple server. Type this in your terminal/console: "python -m SimpleHTTPServer 9081" (or any port number you want to). Then, just open your localhost referring to your specified port.
Open chrome in --allow-file-access-from-files mode
or create a batch file using this following code in Windows. Chrome must be restarted before the configuration takes place.
start "chrome" "C:\Program Files (x86)\Google\Chrome\Application\chrome" --allow-file- access-from-files
exit
I assume you are making a AJAX call to another domain file for which you have to use JSONP as your dataType. Doing this you then dont have to make async = false.
Try this:
before you do the ajax call set display to block, after the ajax call(success or error doesnt matter) - just before you return - set display to none. You dont need displayLoadingImg and the code to handle it. Or do I miss ssomething?
Related
EDIT - PROBLEM SOLVED : It ended up being a server side problem. More details in comments below.
My webpage allows the user to update a graph based on parameters. When a user changes selection (checking/unchecking options), the graph is updated by an Ajax call.
The problem happens when the user quickly checks/unchecks options. When it happens, I made sure the current request is aborted and a new one is made. Here's my simplified code :
function refreshGraph() {
// Abort current running request (if any)
var currentlyLoading = (xhrDashboard != null && xhrDashboard !== undefined);
if (currentlyLoading) {
xhrDashboard.onreadystatechange = null;
xhrDashboard.abort();
}
// Ajax call.
var ajaxParams = {
url: '/Dashboard/ReadyMix/GraphPartial',
data: parameters,
traditional: true,
cache: false,
type: 'POST',
success: function (responseData) {
$(".graphContainer").html(responseData);
},
error: function (xhr, text_status, error_thrown) {
$(".graphZone").html("Error during loading...");
},
complete: function (xhr) {
xhrDashboard = null;
}
};
xhrDashboard = $.ajax(ajaxParams);
}
In Chrome I get the expected behavior. The first (or latest) call is cancelled and the new one is made no matter how many changes the user makes in a short lapse of time (ex : 5 option changes in a few seconds).
Internet Explorer (version 11 tested on multiple machines) start waiting indefinely from the moment I change option fast enough to abort 2 request and start a 3rd one. When launching my app in debug (Visual Studio) it works fine, but as soon as I put it on our sandbox server the problem occurs.
Here's a screenshots with Chrome (sandbox server)
Chrome network screenshot when aborting ajax requests then making a new one
Now here's a screenshot of IE stuck on "waiting"
IE network screenshot when stuck on waiting after aborted ajax requests
Any suggestion would be appreciated.
Hi I'm loading a table with files on a server folder, each row has a "Delete" link that when clicked, it should unlink/remove the file from the server. The code works perfectly fine on my dev server, however, when in prod it doesn't work. I have checked all the code and there doesn't seem to be any difference on the code. I'm not sure if I'm missing some permission related thing on my prod server, but when I click on "delete" the files are not deleted at all. It runs the function below as if it is doing it but the file is still there.
The addfile.php contains:
if (unlink($_GET['videofile'])) {};
The javascript function
function deleteVideo(file_path)
{
var r = confirm("Are you sure you want to delete this Video?");
var j = document.getElementById('vid').value;
if(r == true)
{
$.ajax({
url: 'addfile.php',
data: {'videofile' : file_path },
success: function (response) {
alert('Your file has been removed');
showVideos(j);
},
error: function () {
alert('There was an error removing the file, please try again');
}
});
}
}
The "delete" link looks like:
deleteVideo("videopath")
In your production server, check if your httpd server has permissions to write in video folder.
Take care of allowing unlink a file thought its path, it may be very dangerous. Instead, register your video path on a database, and then passes to function only the ID of video. Also, make sure your user is deleting only the videos he can delete, according to your business rules.
I am developing a local site for a company (only local internal use, offline and without server). I have a main page that has a main div, that contain 3 different div. Each div is linked to a page and the "onclick" event of each div will load the page linked into the main div. So i have to check, with the document ready function, if each page exists and, if not, I want to delete the div linked to that page. How can I check if a page exist locally? I've found many answere that check with status of connection if a page exists, but my html will only work offline and locally, so I can't use that method.
EDIT - SOLVED
I've solved this using the script of #che-azeh:
function checkIfFileLoaded(fileName) {
$.get(fileName, function(data, textStatus) {
if (textStatus == "success") {
// execute a success code
console.log("file loaded!");
}
});
}
If the file was successfully load, i'd change the content of a new hidden div that will tell to another script if it have to remove or not each of the three div.
This function checks if a file can load successfully. You can use it to try loading your local files:
function checkIfFileLoaded(fileName) {
$.get(fileName, function(data, textStatus) {
if (textStatus == "success") {
// execute a success code
console.log("file loaded!");
}
});
}
checkIfFileLoaded("test.html");
I suggest you run a local web server on the client's computer. (See also edit below on local XHR access).
With a local web server they can start it up as if it was an application. You could for example use node's http-server. You could even install it as an node/npm package, which makes deployment also easier.
By using a proper http server (locally in your case) you can use xhr requests:
$(function(){
$.ajax({
type: "HEAD",
async: true,
url: "http://localhost:7171/myapp/somefile.html"
}).done(function(){
console.log("found");
}).fail(function () {
console.log("not found");
})
})
EDIT:
Firefox
Another post has (#che-azeh) has brought to my attention that firefox does allow XHR on the file "protocol". At the time of this writing the above works in firefox using a url of just somefile.html and using the file scheme.
Chrome
Chrome has an option allow-file-access-from-files (http://www.chrome-allow-file-access-from-file.com/). This also allows local XHR request
This flag is intended for testing purposes:
you should be able to run your tests in Google Chrome with no hassles
I would still suggest the local web server as this make you independent of these browser flags plus protect you from regression once firefox/chrome decide to disable support for this.
You can attempt to load the page within a try-catch construct. If the page exists, it will be loaded though. If it doesn't, you can (within the catch) set the related div as hidden.
Try to access the page using $.ajax. Use the error: option to run a callback function that removes the DIV linked to the page.
$.ajax({
url: "page1.html",
error: function() {
$("#page1_div").remove();
});
You can loop this code over all the DIVs.
You can use jquery load function
$("div").load("/test.html", function(response, status, xhr) {
if (status == "error") {
var msg = "Sorry but there was an error: ";
$(this).html(msg + xhr.status + " " + xhr.statusText);
}
});
I'm using $.ajax() to load new pages on my site if certain conditions are met (a flash-based radio player being active). However, I'd prefer not to modify the server-side output for this case.
Now I need a way to embed both the response on my page (that's easily done using .replaceWith()) but also execute javascripts embedded on this page.
One thought I had was creating a dummy div like <div id="onload" data-onload="functionname" data-onload-args="json-for-the-function-args"> but maybe there's a better way that doesn't require changing my html code (i.e. a pure js/jquery solution).
Note that using $(elem).load() is not possible as it does not evaluate any scripts if only a fragment of the retrieved document is used:
// inject the contents of the document in, removing the scripts
// to avoid any 'Permission Denied' errors in IE
I don't know any details about this IE problem but of course whatever code you are going to suggest should not cause errors in recent IE versions (I don't care about IE6).
Something along the lines of:
$('container').html(text_from_ajax_request);
$('container script').each(function(){
var $this = $(this);
src = $this.attr('src');
src ? $.getScript(src) : eval($(this).text());
});
Actually I solved it using a kind of dirty solution that works fine though:
I surround the actual content parts with comments that are not used anywhere else in my server-side template.
Then I fetch the whole content with dataType: 'text' and use string functions to extract the interesting part (this is safe since I look for the first starting comment and the last ending comment, so the actual content cannot cause any problems even if it contains those comments for some reason).
After this I use .html() to update my element. The important thing is that I do not create a DOM element from the retrieved html code since that would break the script tags.
Have you tried using load()? http://api.jquery.com/load/
I believe it should parse scripts and execute them for you.
EDIT:
Ok, either the bit about load() not being usable as is wasn't in the question or I didn't spot it. With that in mind I created a new version of load without the script stripping and it seems to work find in IE6,7,8, Chrome and Firefox... not really sure why the jQuery library does that:
<script type="text/javascript">
$(function() {
setTimeout(function() {
$('#target').load2('inject.html #inject');
}, 5000);
});
jQuery.fn.extend({
load2: function(url, params, callback) {
if (typeof url !== "string" && _load) {
return _load.apply(this, arguments);
// Don't do a request if no elements are being requested
} else if (!this.length) {
return this;
}
var off = url.indexOf(" ");
if (off >= 0) {
var selector = url.slice(off, url.length);
url = url.slice(0, off);
}
// Default to a GET request
var type = "GET";
// If the second parameter was provided
if (params) {
// If it's a function
if (jQuery.isFunction(params)) {
// We assume that it's the callback
callback = params;
params = undefined;
// Otherwise, build a param string
} else if (typeof params === "object") {
params = jQuery.param(params, jQuery.ajaxSettings.traditional);
type = "POST";
}
}
var self = this;
// Request the remote document
jQuery.ajax({
url: url,
type: type,
dataType: "html",
data: params,
// Complete callback (responseText is used internally)
complete: function(jqXHR, status, responseText) {
// Store the response as specified by the jqXHR object
responseText = jqXHR.responseText;
// If successful, inject the HTML into all the matched elements
if (jqXHR.isResolved()) {
// #4825: Get the actual response in case
// a dataFilter is present in ajaxSettings
jqXHR.done(function(r) {
responseText = r;
});
// See if a selector was specified
self.html(selector ?
// Create a dummy div to hold the results
jQuery("<div>")
// inject the contents of the document in, removing the scripts
// to avoid any 'Permission Denied' errors in IE
.append(responseText/*.replace(rscript, "")*/)
// Locate the specified elements
.find(selector) :
// If not, just inject the full result
responseText);
}
if (callback) {
self.each(callback, [responseText, status, jqXHR]);
}
}
});
return this;
}
});
</script>
I do a bunch of json requests with dynamic script tags. Is it possible to detect if there's an error in the request (eg. 503 error, 404 error) and run something on detection of the error?
use ajax instead. AFAIK there is no way to detect if a script tag loads or not, and if not, why it didn't load. Using ajax you can load the json and it will tell you why it didn't load.
Using a library like jQuery this becomes very simple:
$.ajax({
type: "GET",
url: "test.js",
dataType: "script",
error: function(xhr, error, exception){
alert(xhr.status); //Will alert 404 if the script does not exist
}
});
AFAIK, there's no way to access status code of some external asset loaded from the document (such as script, style or image). Even detecting error (via, say, onerror event handler) is not that widely supported across browsers.
If whatever you're loading falls under SOP, use XHR which gives you access to response headers. Otherwise, you can try looking into recently introduced X-domain XHR.
I'm assuming you want this to work cross-domain, which is why you can't use XHR?
Try creating two script tags for each request, the first does your standard JSONP request, the second is basically an error handler.
If the first script tag executes, then clear the error handler in your callback. But if the first gets a 404, the error handler inside the second script tag will be run.
You probably also want to set a timeout, to cope with a slow JSONP response.
http://www.phpied.com/javascript-include-ready-onload/ ?
If you're using jQuery, check out jQuery-JSONP which is a jQuery plugin that does a fairly decent job of doing the <script> insertion for you as well as detecting fetch errors.
Quoting from the project page, jQuery-JSONP features:
error recovery in case of network failure or ill-formed JSON responses,
precise control over callback naming and how it is transmitted in the URL,
multiple requests with the same callback name running concurrently,
two caching mechanisms (browser-based and page based),
the possibility to manually abort the request just like any other AJAX request,
a timeout mechanism.
If you need to cross domains (and need the page to work portably), you have to use dynamic script tags.
If you have access to the remote server, you can pass back an error code from the server, and have the server page return 200.
Whether you have access or not, you can use setTimeout when you create the script tag, passing a function that will trigger an error if it expires before the jsonp handler is called. Make sure that the jsonp handler aborts if the error handler has been called.
You'll need to track each request through a global collection, but you'll gain the ability to cancel and count requests. This is similar to the way that XHR objects are managed by a library like jQuery.
If you want to detect errors, listen for an error event and compare the fileName property of the error with the file name of the script. If they match, you then handle the error. The thing is, I think that the fileName property is Firefox and Opera-only. Most browsers that have a stacktrace for errors can also simulate this behaviour.
Here's an example, as requested by Eric Bréchemier:
var getErrorScriptNode = (function () {
var getErrorSource = function (error) {
var loc, replacer = function (stack, matchedLoc) {
loc = matchedLoc;
};
if ("fileName" in error) {
loc = error.fileName;
} else if ("stacktrace" in error) { // Opera
error.stacktrace.replace(/Line \d+ of .+ script (.*)/gm, replacer);
} else if ("stack" in error) { // WebKit
error.stack.replace(/at (.*)/gm, replacer);
loc = loc.replace(/:\d+:\d+$/, "");
}
return loc;
},
anchor = document.createElement("a");
return function (error) {
anchor.href = getErrorSource(error);
var src = anchor.href,
scripts = document.getElementsByTagName("script");
anchor.removeAttribute("href");
for (var i = 0, l = scripts.length; i < l; i++) {
anchor.href = scripts.item(i).src;
if (anchor.href === src) {
anchor.removeAttribute("href");
return scripts.item(i);
}
}
};
}());