I have the following code making a GET request on a URL:
$('#searchButton').click(function() {
$('#inquiry').load('/portal/?f=searchBilling&pid=' + $('#query').val());
});
But the returned result is not always reflected. For example, I made a change in the response that spit out a stack trace but the stack trace did not appear when I clicked on the search button. I looked at the underlying PHP code that controls the ajax response and it had the correct code and visiting the page directly showed the correct result but the output returned by .load was old.
If I close the browser and reopen it it works once and then starts to return the stale information. Can I control this by jQuery or do I need to have my PHP script output headers to control caching?
You have to use a more complex function like $.ajax() if you want to control caching on a per-request basis. Or, if you just want to turn it off for everything, put this at the top of your script:
$.ajaxSetup ({
// Disable caching of AJAX responses
cache: false
});
Here is an example of how to control caching on a per-request basis
$.ajax({
url: "/YourController",
cache: false,
dataType: "html",
success: function(data) {
$("#content").html(data);
}
});
One way is to add a unique number to the end of the url:
$('#inquiry').load('/portal/?f=searchBilling&pid=' + $('#query').val()+'&uid='+uniqueId());
Where you write uniqueId() to return something different each time it's called.
Another approach to put the below line only when require to get data from server,Append the below line along with your ajax url.
'?_='+Math.round(Math.random()*10000)
/**
* Use this function as jQuery "load" to disable request caching in IE
* Example: $('selector').loadWithoutCache('url', function(){ //success function callback... });
**/
$.fn.loadWithoutCache = function (){
var elem = $(this);
var func = arguments[1];
$.ajax({
url: arguments[0],
cache: false,
dataType: "html",
success: function(data, textStatus, XMLHttpRequest) {
elem.html(data);
if(func != undefined){
func(data, textStatus, XMLHttpRequest);
}
}
});
return elem;
}
Sasha is good idea, i use a mix.
I create a function
LoadWithoutCache: function (url, source) {
$.ajax({
url: url,
cache: false,
dataType: "html",
success: function (data) {
$("#" + source).html(data);
return false;
}
});
}
And invoke for diferents parts of my page for example on init:
Init: function (actionUrl1, actionUrl2, actionUrl3) {
var ExampleJS= {
Init: function (actionUrl1, actionUrl2, actionUrl3) ExampleJS.LoadWithoutCache(actionUrl1, "div1");
ExampleJS.LoadWithoutCache(actionUrl2, "div2");
ExampleJS.LoadWithoutCache(actionUrl3, "div3");
}
},
This is of particular annoyance in IE. Basically you have to send 'no-cache' HTTP headers back with your response from the server.
For PHP, add this line to your script which serves the information you want:
header("cache-control: no-cache");
or, add a unique variable to the query string:
"/portal/?f=searchBilling&x=" + (new Date()).getTime()
If you want to stick with Jquery's .load() method, add something unique to the URL like a JavaScript timestamp. "+new Date().getTime()". Notice I had to add an "&time=" so it does not alter your pid variable.
$('#searchButton').click(function() {
$('#inquiry').load('/portal/?f=searchBilling&pid=' + $('#query').val()+'&time='+new Date().getTime());
});
Do NOT use timestamp to make an unique URL as for every page you visit is cached in DOM by jquery mobile and you soon run into trouble of running out of memory on mobiles.
$jqm(document).bind('pagebeforeload', function(event, data) {
var url = data.url;
var savePageInDOM = true;
if (url.toLowerCase().indexOf("vacancies") >= 0) {
savePageInDOM = false;
}
$jqm.mobile.cache = savePageInDOM;
})
This code activates before page is loaded, you can use url.indexOf() to determine if the URL is the one you want to cache or not and set the cache parameter accordingly.
Do not use window.location = ""; to change URL otherwise you will navigate to the address and pagebeforeload will not fire. In order to get around this problem simply use window.location.hash = "";
You can replace the jquery load function with a version that has cache set to false.
(function($) {
var _load = jQuery.fn.load;
$.fn.load = function(url, params, callback) {
if ( typeof url !== "string" && _load ) {
return _load.apply( this, arguments );
}
var selector, type, response,
self = this,
off = url.indexOf(" ");
if (off > -1) {
selector = stripAndCollapse(url.slice(off));
url = url.slice(0, off);
}
// 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 (params && typeof params === "object") {
type = "POST";
}
// If we have elements to modify, make the request
if (self.length > 0) {
jQuery.ajax({
url: url,
// If "type" variable is undefined, then "GET" method will be used.
// Make value of this field explicit since
// user can override it through ajaxSetup method
type: type || "GET",
dataType: "html",
cache: false,
data: params
}).done(function(responseText) {
// Save response for use in complete callback
response = arguments;
self.html(selector ?
// If a selector was specified, locate the right elements in a dummy div
// Exclude scripts to avoid IE 'Permission Denied' errors
jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :
// Otherwise use the full result
responseText);
// If the request succeeds, this function gets "data", "status", "jqXHR"
// but they are ignored because response was set above.
// If it fails, this function gets "jqXHR", "status", "error"
}).always(callback && function(jqXHR, status) {
self.each(function() {
callback.apply(this, response || [jqXHR.responseText, status, jqXHR]);
});
});
}
return this;
}
})(jQuery);
Place this somewhere global where it will run after jquery loads and you should be all set. Your existing load code will no longer be cached.
Try this:
$("#Search_Result").load("AJAX-Search.aspx?q=" + $("#q").val() + "&rnd=" + String((new Date()).getTime()).replace(/\D/gi, ''));
It works fine when i used it.
I noticed that if some servers (like Apache2) are not configured to specifically allow or deny any "caching", then the server may by default send a "cached" response, even if you set the HTTP headers to "no-cache". So make sure that your server is not "caching" anything before it sents a response:
In the case of Apache2 you have to
1) edit the "disk_cache.conf" file - to disable cache add "CacheDisable /local_files" directive
2) load mod_cache modules (On Ubuntu "sudo a2enmod cache" and "sudo a2enmod disk_cache")
3) restart the Apache2 (Ubuntu "sudo service apache2 restart");
This should do the trick disabling cache on the servers side.
Cheers! :)
This code may help you
var sr = $("#Search Result");
sr.load("AJAX-Search.aspx?q=" + $("#q")
.val() + "&rnd=" + String((new Date).getTime())
.replace(/\D/gi, ""));
Related
I have a javascript that needs to pass data to a php variable. I already searched on how to implement this but I cant make it work properly. Here is what I've done:
Javascript:
$(document).ready(function() {
$(".filter").click(function() {
var val = $(this).attr('data-rel');
//check value
alert($(this).attr('data-rel'));
$.ajax({
type: "POST",
url: 'signage.php',
data: "subDir=" + val,
success: function(data)
{
alert("success!");
}
});
});
});
Then on my php tag:
<?php
if(isset($_GET['subDir']))
{
$subDir = $_GET['subDir'];
echo($subDir);
}
else
{
echo('fail');
}?>
I always get the fail text so there must be something wrong. I just started on php and jquery, I dont know what is wrong. Please I need your help. By the way, they are on the same file which is signage.php .Thanks in advance!
When you answer to a POST call that way, you need three things - read the data from _POST, put it there properly, and answer in JSON.
$.ajax({
type: "POST",
url: 'signage.php',
data: {
subDir: val,
}
success: function(answer)
{
alert("server said: " + answer.data);
}
});
or also:
$.post(
'signage.php',
{
subDir: val
},
function(answer){
alert("server said: " + answer.data);
}
}
Then in the response:
<?php
if (array_key_exists('subDir', $_POST)) {
$subDir = $_POST['subDir'];
$answer = array(
'data' => "You said, '{$subDir}'",
);
header("Content-Type: application/json;charset=utf-8");
print json_encode($answer);
exit();
}
Note that in the response, you have to set the Content-Type and you must send valid JSON, which normally means you have to exit immediately after sending the JSON packet in order to be sure not to send anything else. Also, the response must come as soon as possible and must not contain anything else before (not even some invisible BOM character before the
Note also that using isset is risky, because you cannot send some values that are equivalent to unset (for example the boolean false, or an empty string). If you want to check that _POST actually contains a subDir key, then use explicitly array_key_exists (for the same reason in Javascript you will sometimes use hasOwnProperty).
Finally, since you use a single file, you must consider that when opening the file the first time, _POST will be empty, so you will start with "fail" displayed! You had already begun remediating this by using _POST:
_POST means that this is an AJAX call
_GET means that this is the normal opening of signage.php
So you would do something like:
<?php // NO HTML BEFORE THIS POINT. NO OUTPUT AT ALL, ACTUALLY,
// OR $.post() WILL FAIL.
if (!empty($_POST)) {
// AJAX call. Do whatever you want, but the script must not
// get out of this if() alive.
exit(); // Ensure it doesn't.
}
// Normal _GET opening of the page (i.e. we display HTML here).
A surer way to check is verifying the XHR status of the request with an ancillary function such as:
/**
* isXHR. Answers the question, "Was I called through AJAX?".
* #return boolean
*/
function isXHR() {
$key = 'HTTP_X_REQUESTED_WITH';
return array_key_exists($key, $_SERVER)
&& ('xmlhttprequest'
== strtolower($_SERVER[$key])
)
;
}
Now you would have:
if (isXHR()) {
// Now you can use both $.post() or $.get()
exit();
}
and actually you could offload your AJAX code into another file:
if (isXHR()) {
include('signage-ajax.php');
exit();
}
You are send data using POST method and getting is using GET
<?php
if(isset($_POST['subDir']))
{
$subDir = $_POST['subDir'];
echo($subDir);
}
else
{
echo('fail');
}?>
You have used method POST in ajax so you must change to POST in php as well.
<?php
if(isset($_POST['subDir']))
{
$subDir = $_POST['subDir'];
echo($subDir);
}
else
{
echo('fail');
}?>
Edit your javascript code change POST to GET in ajax type
$(document).ready(function() {
$(".filter").click(function() {
var val = $(this).attr('data-rel');
//check value
alert($(this).attr('data-rel'));
$.ajax({
type: "GET",
url: 'signage.php',
data: "subDir=" + val,
success: function(data)
{
alert("success!");
}
});
});
});
when you use $_GET you have to set you data value in your url, I mean
$.ajax({
type: "POST",
url: 'signage.php?subDir=' + val,
data: "subDir=" + val,
success: function(data)
{
alert("success!");
}
});
or change your server side code from $_GET to $_POST
Every day the contents of this request changes: the problem is that the browsers (IE and Chrome for sure), are ALWAYS displaying the OLD result (first get) until I clear the cache!
How can I solve this issue???
$('#q').keyup(function(){
var param = $(this).val();
if(param == ''){
return
}
if(param != ''){
$('#p_a').html('');
}
$.ajax({
url: 'ajax.php',
data: {qty: param},
type: 'GET',
success: function(result){
$('#p_a').html(result);
},
error: function(result){
$('#p_a').html('Error');
},
});
});
PHP:
<?php
if(isset($_GET['qty'])){
$cq = $_GET['qty'];
$cq = $link->real_escape_string($cq);
$GetP = $link->query("CALL GetPrice($cq)") or die('Query Error');
if(mysqli_num_rows($GetP) === 1){
while($p = mysqli_fetch_array($GetP)){
echo $p['values'];
echo $p['dates'];
}
}else{
echo 'More Rows';
}
}
?>
EDIT:
Is this jQuery function a/the right/best/good working solution? From the documentation:
cache (default: true, false for dataType 'script' and 'jsonp')
Type: Boolean
If set to false, it will force requested pages not to be cached by the browser. Note: Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_={timestamp}" to the GET parameters. The parameter is not needed for other types of requests, except in IE8 when a POST is made to a URL that has already been requested by a GET.
You can either set cache: false in your $.ajax() call or if you want the caching to affect all the requests in a given page you can do
$.ajaxSetup({ cache: false });
This will add a _=32409035094 to the query string being a parameter named _ and a value of the current timestamp. This creates a unique request string causing the request to be read from the server rather than the cache.
I am writing a javascript which will post hostname of the site to a php page and get back response from it, but I don't know how to assign the hostname to adrs in url and not sure that code is correct or not.And this needs to done across server
javascript:
function ursl()
{
$.ajax({
url: 'http://example.com/en/member/track.php?adrs=',
success: function (response)
if (response)=='yes';
{
alert("yes");
}
});
}
track.php
$url=$_GET['adrs'];
$sql="SELECT * FROM website_ad where site='$url'";
$res=mysqli_query($link,$sql);
if(mysqli_num_rows($res)==0)
{
echo"no";
}
else
{
echo"yes";
}
Your ajax function should be written thusly:
$.ajax({
url: 'http://example.com/en/member/track.php?adrs=' + window.location.hostname,
success: function (response) {
if (response === 'yes') {
$.getScript('http://example.com/en/pop.js', function () {
// do anything that relies on this new script loading
});
}
}
});
window.location.hostname will give you the host name. You are passing it to the ajax url by concatenating it. Alternatively, as katana314 points out, you could pass the data in a separate parameter. Your ajax call would then look like this:
$.ajax({
url: 'http://example.com/en/member/track.php?adrs=',
data: {adrs: window.location.hostname},
success: function (response) {
if (response === 'yes') {
$.getScript('http://example.com/en/pop.js', function () {
// do anything that relies on this new script loading
});
}
}
});
I'm not sure what you intend response to be, but this code assumes it is a string and will match true if the string is 'yes'. If response is meant to be something else, you need to set your test accordingly.
$.getScript() will load your external script, but since it's asynchronous you'll have to put any code that is dependent on that in the callback.
In this type of GET request, the variable simply comes after the equals sign in the URL. The most basic way is to write this:
url: 'http://example.com/en/member/track.php?adrs=' + valueToAdd,
Alternatively, JQuery has a more intuitive way of including it.
$.ajax({
url: 'http://example.com/en/member/track.php',
data: { adrs: valueToAdd }
// the rest of the parameters as you had them.
Also note that you can't put a script tag inside a script. You will need some other way to run the Javascript function mentioned; for instance, wrap its contents in a function, load that function first (with a script tag earlier in the HTML), and then call it on success.
And for the final puzzle piece, you can retrieve the current host with window.location.host
You'll need to change this line to look like so:
url: 'http://example.com/en/member/track.php?adrs='+encodeURIComponent(document.URL)
The full success function should look like so:
success: function (response){
if (response==="yes"){
//do your thing here
}
}
That should solve it...
I need to load only new data into my div with ajax. At the moment I'm currently loading all data, because if I delete a record in the database it also removes it from my chat div.
Here is my js code:
var chat = {}
chat.fetchMessages = function () {
$.ajax({
url: '/ajax/client.php',
type: 'post',
data: { method: 'fetch', thread: thread},
success: function(data) {
$('.chat_window').html(data);
}
});
}
chat.throwMessage = function (message) {
if ($.trim(message).length != 0) {
$.ajax({
url: '/ajax/client.php',
type: 'post',
data: { method: 'throw', message: message, thread: thread},
success: function(data) {
chat.fetchMessages();
chat.entry.val('');
}
});
}
}
chat.entry = $('.entry');
chat.entry.bind('keydown', function(e) {
if(e.keyCode == 13) {
if($(this).val() == ''){
} else {
chat.throwMessage($(this).val());
e.preventDefault();
}
}
});
chat.interval = setInterval(chat.fetchMessages, 8000);
chat.fetchMessages();
I have had a look around and some say that if you pass a timestamp to the server and load new content that way, but I can't seem to get my head around that. If you need php let me know.
Right, so the timestamp thing makes the most sense. You'll need to do a few things:
On the back end, you need to make client.php accept a timestamp parameter in the querystring. When returning data, instead of just returning all of it, make it return everything since the time stamp, if given. Otherwise return everything.
The very first time you load the chat client, the first thing you should do is make an Ajax call to a new PHP file that returns the current server timestamp. Store the value of that in a Javascript variable as a Number.
During chat.fetchMessages(), increment the value of the timestamp variable by however long it's been since the last fetch (looks like 8000 milliseconds), and feed that to client.php, like url: '/ajax/client.php?timestamp=' + latestFetchTimestamp,
Instead of replacing all HTML content, append instead.
NOTE:
I gave up on trying to do the processing in one go, and just let it return after every x number of sends.
Two paths,
/sms?action=send
/sms?action=status
Let's say that the send path starts sending 10,000 sms messages via REST api calls.
I make a call to that page via ajax.
Then every few seconds, I make a call to /sms?action=status to see how the progress is going, and to update a progress bar.
The status path returns false if no messages are being sent.
What ends up happening is that the ajax call to the SEND path gets the ajax success: function called almost instantly, even though I know the script is taking 1+ minute to complete execution.
My progress bar never gets shown because the status ajax call (which is in a set interval with a few second delay) never seems to actually get called until the send call completes.
I'm trying to put the relevant code in here, but it may not be as clear as it should be without all the context.
<script type="text/javascript">
var smsInterval = 0;
var smsSending = false;
$(document).ready(function() {
var charCount = 0;
var smsText = "";
var smsTotal = <?php echo $options["smsTotal"]; ?>;
<?php if($options["sending"]): ?>
smsStatus();
smsSending = true;
smsInterval = setInterval("smsStatus()", 5000);
<?php endif; ?>
$("span#smsadmin_charcount").html(charCount.toString());
//send button
$("div#smssend").click(function() {
if(smsSending == true) {
return false;
}
smsStatus();
var dataString = $("#smsadmin_form").serialize();
smsSending = true;
$("div#smssend").html("Sending...");
$.ajax({
type: "POST",
url: "<?php echo $base_url; ?>/admin/sms",
data : dataString,
success: function(data) {
},
error: function(request, error) {
$("div.notice.sms").html("ERROR "+error+ "REQUEST "+request);
}
});
});
});
function smsStatus() {
var dataString = "smsaction=status&ajax=true";
$.ajax({
type: "POST",
url: "<?php echo $base_url; ?>/admin/sms",
data : dataString,
success: function(data) {
//data being false here indicates the process finished
if(data == false) {
clearInterval(smsInterval);
var basewidth = $("div.sms_progress_bg").width();
$("div.sms_progress_bar").width(parseInt(basewidth));
$("div.sms_progress_notice").html(parseInt(100) + "% Complete");
smsSending = false;
$("div#smssend").html("Send To <?php echo $options["smsTotal"]; ?> Recipients");
} else {
var pcomplete = parseFloat(data);
$("div.sms_progress_bg").show();
var basewidth = $("div.sms_progress_bg").width();
$("div.sms_progress_bar").width(parseInt(basewidth * pcomplete));
$("div.sms_progress_notice").html(parseInt(pcomplete * 100) + "% Complete");
}
},
error: function(request, error) {
$("div.notice.sms").html("ERROR "+error+ "REQUEST "+request);
}
});
}
I might be missing the point, but inside the $("div#smssend").click you got this line:
smsStatus();
shouldn't it be:
smsInterval = setInterval("smsStatus()", 5000);
and INSIDE the success: function(data) for /admin/sms ?
If the send part is sending out 10k messages, and the status returns true if currently sending a message, and false if in between sending, then you have a design issue.
For example, what is status supposed to be showing?
If status is to show how many of a certain block have been sent, then what you can do is to submit the message to be sent (or addresses), and get back some id for that block.
Then, when you ask for a status, pass the id, and your server can determine how many of that group has been sent, and return back the number that were successful, and unsuccessful, and how many are still pending. If you want to get fancy, you can also give an indication how much longer it may be before finishing, based on how many other requests are also pending.
But, how you approach this really depends on what you expect when you ask for the status.