I have an Ajax widget that monitors the status of a connection on a web page, and alerts the user when the server can no longer be reached. It works on Windows 7, but fails on Mac OSX 10.5.8 (both Safari and Firefox).
The crucial code is here:
(function(e){
e.fn.checknet=function(config){
function checkConnection(config){
e.ajax({
url:config.checkURL,
cache:false,
success:function(){
window.checknet.conIsActive=true
},
error:function(){
window.checknet.conIsActive=false
},
complete:function(){
if(window.checknet.conIsActive){
connectionExtablished()
}
else{
connectionLost()
}
}
})
setTimeout(
function(){checkConnection(config)},
config.checkInterval
)
}
}
})(jQuery);
I'm calling it every five seconds. When I shut down the server, Windows browsers do indeed notice within five seconds. However, the browsers on my Mac need about two and a half minutes.
From other questions, I gather that caching can be an issue. However, I've tried inserting parameters:"defeatcache=" + new Date().getTime() to the Ajax call and $.ajaxSetup({ cache: false }); before the Ajax call; neither works.
Does anybody have any suggestions for how I can get my Mac browsers to notice the downed connection sooner?
As mentioned in the comment and here How to disable Ajax caching in Safari browser?, you need to append the paramater to the URL, I'm not sure what this bit is doing parameters:"defeatcache=" but the way I have always used it is on the url:
url = url + '&nocache=' + new Date().getTime();
To modify your example where checkURL is the plain url unedited it should be
url:config.checkURL + '&nocache=' + new Date().getTime(),
If the above still does not work you want to add no-cache headers to the URL you are trying to access - for example if the url you were accessing was called "status.php" then you could try adding no-cached headers to the status.php page itself:
header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1.
header('Pragma: no-cache'); // HTTP 1.0.
Obviously this code above (for PHP) would be different depending on your sever side language (taken from & more examples for other server side languages here: einternals)
when you make your .ajax() call use the option cache: false
.ajax(
{url: 'http://...',
cache: false });
or
before your ajax call use ajaxSetup
$.ajaxSetup({ cache: false });
I used to disable caching in the response's header. So in the service that provides the response, look into setting various fields to disable caching from that end of the call. Sorry I don't have any ready examples!! Hope this helps.
Related
I'm trying to configure caching for slow API requests. I've found that default cache configuration doesn't work for my case.
My Nginx server has the following configuration:
location /api/get_data_from_cache_with_timeout2sec {
expires 10m;
proxy_pass http://myapp;
}
Server response has the following headers:
cache-control: max-age=600
expires: Mon, 29 Jun 2020 14:56:31 GMT
And page makes AJAX request with this code (this is just a simple example):
jQuery.get('/api/get_data_from_cache_with_timeout2sec', null,
function(data, status, xhr) {});
How I expect it should work:
The browser should recognize ерфе the content should be cached. The browser should get the data from the cache, and it should be faster than 100ms for the second request (using browser cache).
How it works:
Every time browser spends 2 seconds to get the content, and the browser doesn't try to cache the content for this request, and it doesn't provide the content from the cache for the user.
What should I change in configuration or code to make it possible to cache such requests with a browser and make it faster? Thank you!
Please find the example page where you can reproduce it (just click the "Check Now" button several times):
https://www.iwebtool.com/cache_example
After some investigation I've found that the following command should be executed before the browser will be able to cache the ajax requests data:
$.ajaxSetup({ cache: true});
So, this code works as expected (with caching):
$.ajaxSetup({ cache: true});
jQuery.get('/api/get_data_from_cache_with_timeout2sec', null,
function(data, status, xhr) {});
I hope it will help someone else.
I know this question has been address many times on Stack Overflow, but none of the solutions are working for me.
I can't get ANY ajax requests to complete within my phonegap application when running on the device (Android 4.4.2), yet everything works fine from desktop browsers.
First I tried AngularJS $http
Then I tried jQuery .get
Then I tried raw xhr
In all cases, the request immediately fails with no response. I've tried requesting data from my own servers, and from google servers, and elsewhere, all the same. I've tried whitelisting my domains in config.xml, in many forms, still no effect. I've even opened the console, and manually created an XHR and tried to GET on it, and the same thing happens. The request immediately fails. If anyone can please help me out, that would be great. I'm on the latest version of pretty much all my software, having set up my dev environment just today.
Cross domain request headaches. The browser allows the cross domain request but phonegap on the device kills it. I've been there and it took some work getting used to dealing with it. Try using jquery and jsonp in an ajax get request.
Try adding <access origin="*" /> to your config.xml for testing.
Here's an example of an jquery ajax request taken from working code.
$.ajax({
timeout: 5000,
url: 'https://yourdomain.com/yourfile.php',
dataType: "jsonp",
jsonpCallback: 'yourcallbackfunction',
type: "GET",
crossDomain: true,
data: {'somedata':'your data string'},
error: function(xhrObj,text,errorObj){
if(xhrObj.status !== 200) {
var errorTxt='Error Log: ';
errorTxt=errorTxt+"Error code specific:'"+xhrObj.status+"'\n";
errorTxt=errorTxt+"Error status specific:'"+xhrObj.statusText+"'\n";
errorTxt=errorTxt+"Error code general:'"+text+"'\n";
errorTxt=errorTxt+"Error status general:'"+errorObj.message+"'\n";
console.log(errorTxt);
}
}
});
function yourcallbackfunction(data) {
// do cool stuff here
console.log(data);
}
Be sure to handle the headers on your servers response so that the response gets back to your client. Here's a sample processing function I used to return data. Sorry if php isn't your server side scripting language but hopefully you'll get the idea.
`function SendResults($data) {
// Allow from any origin
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
header("content-type: application/json");
$callback = filter_input(INPUT_GET, 'callback', FILTER_SANITIZE_SPECIAL_CHARS);
echo "$callback(" . json_encode($data) . ")";
}`
Good luck.. Hope this helps you.
As the title says, I'm trying to access (POST) using jQuery AJAX call to a web url, http://host:port/... or http://localhost:8080/... from a local HTML file, c:\home.html. I can't get it to work.
I did Google and also saw several questions here but I can't get it to work. I need some help here. Here is what I've tried so far.
dataType: jsonp
crossDomain: true
Setting the header in my response:
response.setHeader("Access-Control-Allow-Origin", "*");
None of the three browsers are working - IE, FF or Chrome. The request is never reaching the server. Here are some of the errors I'm seeing.
No Transport (IE) if not jsonp is used.
NS_BINDING_ABORTED / Error loading content (NS_ERROR_DOCUMENT_NOT_CACHED) in FF
This is my code. I would appreciate any help. I'm using jquery-1.8.2.min.js.
var http_host = "http://localhost:8080";
function su (pc, p) {
var suUrl = http_host + "/ps/api/v2/authorize.json";
$.ajax({
type: 'POST',
url: suUrl,
data: {
phone_cell: pc,
password: p,
},
dataType: "json",
crossDomain: true,
success: osu,
error: oe
});
return false;
}
function osu (d) {
console.log(d);
}
function oe(xhr, ts, et) {
alert("ServerError: " + et);
}
An example would be a perfect pointer.
I suppose my code got messed up w/ all the different solutions that I was trying. I was finally able to get it to work w/ setting the header (solution that was recommended and worked for others). All that I had to do to get it to work is add the following to my REST service response.
response.setHeader("Access-Control-Allow-Origin", "*");
Update:
I thought I figured this out but I've not. There is more it than just setting the header. Anyways, in my specific situation. I was trying to run my app (html, js) off of the hard drive specifically on chrome and trying to access web services available on the cloud.
Here is how I finally solved the problem. I started the chrome w/ the following parameters.
--disable-web-security -–allow-file-access-from-files
Like I mentioned earlier, this app is really a desktop application that will be run as part of the chromium embedded framework.
Thanks every one for your input.
You can't make a cross-domain request from a local file because it's not on a domain. You need to host C:\home.html on a local webserver instance in order for it to work.
I am having a rather frustrating problem with the jquery post function that probably stems from not understanding how it works correctly.
I have a function that should post some form information to a php script that I wrote and that script then runs curl requests against an API to get around the cross-domain policy of javascript. It seems to work fine as long as it submits to "http" but when I send it to "https" the form never gets submitted.
I ran wireshark on my computer and it showed no traffic towards the destination ip until I made the url use http. I have basic auth on the server so I am passing the user and password through the url, but tested without that there and got the same results.
Here is the not working code:
$j.post("https://<api user>:<password>#<ip>:444/ProxyScript.php",
$j("#spoke_ticket").serialize(),
function(msg) {
log_status(msg);
fade_status();
$j(':input','#createtheticket')
.not(':button, :submit, :reset, :hidden')
.val('')
.removeAttr('checked')
.removeAttr('selected');
});
Here is the working function:
$j.post("http://<other ip>/ProxyScript.php",
$j("#spoke_ticket").serialize(),
function(msg) {
log_status(msg);
fade_status();
$j(':input','#createtheticket')
.not(':button, :submit, :reset, :hidden')
.val('')
.removeAttr('checked')
.removeAttr('selected');
});
Any ideas as to why the traffic is not being sent?
Let me know if I left out some key information or anything.
Thanks for the help
If you are doing the AJAX post from a http page to a https URL then the Cross-Domain policy kicks in because the protocol is also part of the origin specification, as it is described here. The browser will refuse to make the AJAX call, so that's why you're not seeing any traffic.
A solution is discussed here:
Ajax using https on an http page
So your best bet is the Access-Control-Allow-Origin header which should be supported on most modern browsers now.
So make your server add the following header to the responses:
Access-Control-Allow-Origin: https://www.mysite.com
If for some reason you cannot enforce this, then the only choice left would be JSONP.
Why not use a proxy to get over the cross-domain issue? It sounds more easy. An simple example is when i want to retrieve the danish administration national geo-data for counties,road names and so on (lucky for me, their data is in json or XML optional)
simplified proxy.php
<?
header('Content-type: application/json');
$url=$_GET['url'];
$html=file_get_contents($url);
echo $html;
?>
in ajax, get the lat/longs for a county borderline
var url= "proxy.php?url=https://geo.oiorest.dk/"+type+"/"+nr+"/graense.json";
$.ajax({
url: url,
dataType: 'json',
success: function (data) {
...
});
notice the https - the url could be, real example, https://geo.oiorest.dk/kommuner/0810/graense.json
I'm using jQuery (1.7.0) to make a json/ajax call to Spotify. The following code works fine in Chrome and Firefox, but causes an error (Error: Access is denied.) in IE.
$.ajax({
url: 'http://ws.spotify.com/lookup/1/.json',
type: 'GET',
dataType: 'json',
cache: true,
data: {
uri: "someartist",
extras: "album"
},
success: successfn,
error:function(xhr, status, errorThrown) {
alert("networking error: "+errorThrown+'\n'+status+'\n'+xhr.statusText);
}
});
The success function is called in Chrome and FF, but the error function is called in IE with the above message. I have set cors to true: jQuery.support.cors = true;.
It works on Chrome and FF both locally and on my server, it works in IE locally but not on the server. Changing cache: false causes problems at the spotify end - doesn't line additional parameters, so I get a "bad request" error.
Grateful for any pointers.
Thanks
Abo
You are relying on the spotify url to give a Access-Control-Allow-Origin:* in their header to allow cross domain requests from all domains. Internet explorer however doesn't support this, so it gives access denied.
access-control-allow-origin explained. (TLDR: Servers may allow cross domain ajax in their headers)
If you need this to work in IE, you could use spotify's JSONP API if they have one or make the AJAX request in flash, which works in all browsers and passes the requests response data to your javascript.
The above answer about using jsonp is correct; I want to add:
Don't set
jquery.support.cors = true;
I'm not sure why so many questions begin by stating they took that step. This property is meant to be read to find out if the browser supports CORS. You should only override it if you know differently, and in my experience it's accurate for all major browsers. Setting it to true doesn't enable the browser to use CORS, it just denies you the info that CORS is going to fail.
http://api.jquery.com/jQuery.support/
can you give an example of returned data?
at a /guess/, it either has something to do with the filename ".json", or the JSON returned has something weird about it.
I'm surprised this works on Chrome or Firefox. You shouldn't be able to run cross-domain JSON requests.
If Spotify API supports it, you should use JSONP in order to access resources from other domains.
Also see: No response from jQuery ajax call
I don't see this working in FF. You can't make cross-domain Ajax calls. So I'm not sure what's going on when you say that it works in FF. But I just tried the following in FF and I got the error. So all you can do is make the call on the server side and then include the results in your page.
http://jsfiddle.net/2XWGn/