JQuery error $ .ajax "async: false"?
I would be grateful for your opinion / advice regarding the following
Scenario
There is a PDF alias in HTML and there is a URL at the end for each nickname.
Link url always download.php?what=%PDF_Nick%
to ensure loading for disabled JS clients.
For JS-enabled clients, I make a JQuery AJAX call and rewrite the link url from download.php?what=%PDF_Nick%
to http://examplesite.com/requestedPFF.pdf to activate the download from the client. I have set "async: false"
to allow AJAX to get a new url.
Problem
AJAX returns a valid script rewriting the JS url variable, but location.href
runs again before the original url, creating an additional internal call
Do you think this is due to a mistake ignoring the definition "async: false,"
, or a mistake I made and missed in order to catch?
Thank you in advance
Html code
<a href="/download.php?what=PDF_A" onclick="javascript:download
('PDF_A')">Download</a>
JS code
function download ( what ) {
var url = "download.php?what="+what;
$.ajax({
type: "GET",
url: "download.php?ajax=true",
data: "what=" + what
async: false,
dataType: "script"
});
// if AJAX got the download URL I expect actual download to start:
location.href = url;
}
Internal code (download.php)
$myPDF = array();
$myPDF["PDF_A"] = "PDF_A.pdf";
....
$url = "http://examplesite.com/" . $myPDF["PDF_A"];
...
if ( $_GET["ajax"] === "true" ) {
// overwrite JS url variable
print('url = "'.$url.'";');
} else {
header("Location: ". $url );
header("Connection: close");
}
You ran into a review problem here. The variable url in your JS code is declared via the var keyword inside the scope of the load function. This means that only the code inside the download function can change that particular URL value.
The script returned from the download.php file changes the value of the URL in the global scope (in the browser, this is the "window" object) that does not match the URL in the scope of the download function.
If you don't use the 'var' keyword when declaring a url variable, it will be automatically generated in the global scope and your code will function as you expect.
I agree with others that your design is inherently flawed and should be revisited, however.
source to share
Is there any reason you would disable the asynchronous nature of the AJAX request? it will block the browser until the request completes. You are better off using a callback:
$.ajax({
type: "GET",
url: "download.php?ajax=true",
data: "what=" + what,
dataType: "script",
success: function(msg) {
location.href = url;
}
});
source to share
Or you can use an ajax call to sync with .responseText like in this example:
var html = $.ajax({
url: "some.php",
async: false
}).responseText;
For your code, this means:
function download ( what ) {
var url = "download.php?what="+what;
location.href = $.ajax({
type: "GET",
url: "download.php?ajax=true",
data: "what=" + what
async: false,
dataType: "script"
}).responseText;
}
source to share