My goal
I would like to let browsers cache my whole website, but only download the static content when I have changed one or more files.
My situation
After some research I have found a way to do this. That is to add a Far Future Expires Header to my htaccess file and add a querystring to my files using the filemtime() function.
The problem
When I click on the address bar and type in my website address in firefox, then Firebug displays 38.3 KB (36.4 KB from cache)
When I press F5 in firefox, then Firebug displays:241.1 KB (10.9 KB from cache)
Now I have tried to do the same with Google and they are sending HTTP header 304 back. I have read a lot about ETag and the Last Modified header, but I have heard a lot of people saying that they are not really reliable.
My question
What would be the best solution if I would like to send HTTP header 304 back with my static content if the user presses on F5, like Google?
I am asking this question because I am often visiting a website and using F5 to see if there is some new information available. Not to reload the images etcetera.
Update
It seems that Firefox is controlling the way the cache is used and I would like to use the cache also when a user presses F5.
The very purpose of reload is to reload the page. There is no server-side header magic if the browser was witten to ignore caches when the user specifically asks for it.
The solution for Google is that you check if the crawler sent an If-Modified-Since header with:
if ($_SERVER["HTTP_IF_MODIFIED_SINCE"]) {
header("HTTP/1.0 304 Not Modified");
exit();
}
This trick could work for browsers, but not in forced reload modes, like Firefox's SHIFT+RELOAD.
You can also use the newer application cache feature.
I don't know what your target browser is, but most browsers have been supporting it for quite a few versions so far..
This way you can define your statics to be downloaded only once.
For some very good information on the subject you can take a look at this page:
http://diveintohtml5.ep.io/offline.html
I'm not sure I understand the intent of your question, but you can specify the response code in php, with the header function, regardless of whether or not your user presses a button.
http://php.net/manual/en/function.header.php
Related
I'm looking for some help in how best to handle page navigation/redirection from a PHP application. We don't offer many downloads so this has only just now come up as an issue. The gist is that a user loads a webpage to view some data and this page offers a hyperlink to download the data into a spreadsheet (dynamically built). The issue that I'm struggling to come up with a slick solution to is if the user sits on the webpage for long enough to where their session expires in PHP. Suppose in that case the user comes back to the page and clicks the download link.
There are two scenarios I need to handle. The first is with old browsers like IE (have to support it for the time being). IE doesn't support the download attribute for ANCHOR elements. Therefore, when the link is clicked and the session is invalid, the user is presented with a login form but the browser URL now reflects the endpoint of the download. Upon logging in, the download functions correctly but the user is left at the login form because the presence of the Content-Type: attachment makes the browser not navigate. I am looking for how to best get the user back to what is essentially the initial HTTP_REFERER when the download was requested. The only idea I can come up with is either a standard endpoint or query string parameter to use so that my login form handling code can properly redirect after successful login for a download request.
The other scenario is for modern browsers that support the download attribute. My code does set the HTTP response code to 401 when it determines the login form needs to be rendered (maybe that's not correct though). I do not see anything within $_SERVER that alludes to that fact though which suggests, again, a standard endpoint or query string parameter to use for identification. Modern browsers handle this case well by simply denying the download and actually displays that the request needs authorization. So, this works well as long as setting the status to 401 on all login form renders is correct otherwise, I'd again need some way to know that the requested endpoint is a download.
I'd like to avoid any kind of JavaScript solution if possible.
Is there any option to detect if my page is being loaded from a clickjacking page?
I mean, does not matter if the page is the origing of the clickjacking(I've setted the X-FRAME-OPTIONS header), the thing is if from a clickjacked page users are browsing to mine page.
The first solution I found is to control the HTTP-REFERER, but is a hard work because I can't control all my traffic.
Sorry for my english.
Unless you intend for external sites to be able to POST to yours, if you have a POST request originating from another server, it's probably click jacking:
if($_SERVER['REQUEST_METHOD'] == 'POST' && !strstr($_SERVER['HTTP_REFERER'], 'mydomain.com') {
//probably clickjacking
}
If you have pages that use GET that are susceptible to clickjacking, you can either add a check for the HTTP_REFERER on a per-page basis, or change the page to use POST (which is usually best for something which does an update).
One of your options is to set your website header: "X-Frames-Options" to "SAMEORIGIN"
This should prevent your website from being loaded into iframes and frames unless the originating page is in your domain.
Note that this will only work for certain browsers, for example I don't think this will work with IE7 and below and I don't think it works with chrome. This will at least reduce your attack surface a little bit.
Apache:
Header always append X-Frame-Options SAMEORIGIN
MDN - The X-Frame-Options response header
EDIT: Now that I understand better...
Perhaps you can use code similar to this:
if (window.top !== window.self) {
// do something here
}
This is one way to detect if the page is loaded into an iframe. You could set a cookie here, call a WebService here, or use window.location.href to navigate.
Here is an example of the "frame-busting" defense for click jacking:
Clickjacking Defense
-KB
Some pages can be prefetched by the browser (see this or that). How to detect in PHP that a request is a prefetched request ?
Is there any method is not browser-specific ?
(PS: I use Apache.)
I was looking for a similar answer to stop FF and other browsers throwing out my server side page counts.
Firefox
Chrome white paper
According to the articles above, Firefox sends a header which makes it easy to detect but the Chrome white paper states that Chrome doesn't give any indication to the server. The Chrome white paper notes that external analytic solutions (scripts written in JS) will not count the prefetch hits when they use the page visibility API.
My suggestion is to write your own JS script to detect if the page is ever made visible.
This question is very similar to "How to detect if cookies are enabled?". But you must use client-side redirection, because prefetched page start loading after loading main page.
Directly prefetch request can by detected by header (X-Moz: prefetch for FF) or by passing additional param to a link.
P.S. Without cookies enabled you cannot detect it for client, only for each directory prefetch request.
Using PHP I'm trying to download/save the following image:
http://www.bobshop.nl/catalog/product_image.php?size=detail&id=42428
When you load this image in a browser, you can see it, but when I try to download it using several different methods, I get an 1 KB file that says that the product could not be found on the server.
I tried this with both the file_put_contents and the curl way.
I even used the function get_web_page that I found somewhere on StackOverflow, to catch a possible redirect.
What else could be the reason that you can see the image in a browser, but no way to download it ?
UPDATE:
Thanks to an error that was thrown trying out the different answers, I just found out the real cause of the problem. Somewhere in the process of scraping the html, the URL got & instead of & . I replace these now and every other method works now too... thanks all!
I just implemented a simple way to download and store and it worked:
<?php
$fileContent = implode("",file("http://www.bobshop.nl/catalog/product_image.php?size=detail&id=42428"));
$fp = fopen("/tmp/image","w+");
fwrite($fp, $fileContent);
fclose($fp);
?>
Are you behind a proxy? This could be the problem (you are with proxy configured but php not) ;)
There is likely some kind of header checking that is being done with this PHP script to ensure that a browser is requesting the image and not someone trying to scrape their content. This can be forged (although after doing something like this I feel like I need to take a shower) with cURL. Specifically, curl_setopt():
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'User-agent: Some legitimate string'
));
To find out which headers need to be sent, you'll need to do some experimentation. If you have Google Chrome, you've probably used the Inspector (If you don't Firefox has similar addons, so you can use something like Firebug). If you request the image with Chrome, you can right click to inspect it. Go to the Network tab. Now refresh the page. The request to product_image.php should show up. If you click on it and click the Headers tab, you should see a list of headers sent. My browsers sends: User-Agent, Accept, Accept-Encoding, Accept-Language, and Accept-Charset.
Try combinations of these headers with valid values to see which ones need to be sent for the image to be returned. I'd bet that this site probably only checks User-agent so start with that one.
An important note: You should cache the result of this call, because it will be very suspicious if your server requests the image multiple times in rapid succession (say if many users on your site request the script that grabs this image). Also as an extra layer of anonymity, you might want to pick your User-agent from an array of valid ones so bobshop.nl thinks that all of the requests are coming from users behind a large network (like a college campus). You can find valid user agent strings on UserAgentString.com.
So in most current browsers there is the feature of Tabs, is there a way to get the Tab index?
so Tab 1 has www.google.com opened in it and Tab 2 has www.google.com opened in it, is there a way to identify what the Tab index is?
Pseudo Code:
if($tab == 2) {
alert "Tab 2 is active\n";
}
if($tab == 1) {
alert "Please use Tab 2 as this is Tab 1\n";
}
Funny as everything I search for about tabs is related to the tab index of the webpage itself, sigh...
Strictly speaking. TABS are on the end user's machine. PHP works on the server. PHP can't see what the end user's machine is doing, it can only serve the end user PHP'ed pages.
Google does this with JavaScript and Cookies. For every instance of the page opened, increment a cookie counter. If the counter > 1, use AJAX to display an error message. Also, prohibit the page from functioning if cookies or JavaScript is disabled.
Look into jQuery.
As far as determining the absolute tab index, I know of no way to do it with Javascript. You can identify windows by their names, but not anything else.
In your example of two tabs containing the same web page, you should be able to uniquely identify them by making them aware of each other. You'd need to use cookies for this. Essentially, when a page is loaded, it would check for a cookie that tells it about other instances of the page that are currently loaded, and make decisions accordingly.
In this scenario, your onload handler would check the cookies, and register the loading page. You'd also need an onunload handler to unset the cookie pertaining to the page being unloaded.
See Javascript communication between browser tabs/windows for more information on how to use cookies to communicate between windows with Javascript.
in php: definitely not - it's executed on your server without access to the cleints browser.
maybe there's a solution using javascript (but i've never heard of that, and i'm pretty sure this isn't possible too - at least not as a cross-browser solution).
i think the best chance you'll have (if there even is one) is using other client-side languages like flash, silverlight or a java-plugin as this ones can do a lot more than javascript - but i'm sorry i don't know any of these good enough to give more information or hints.
Don't waste anymore time on this mate. It isn't possible, mainly because any webpage inside browser will not be able to get this kind of information due to security restrictions.
Try looking for an laternative approach as some of the other guys have suggested in their comments.
I am sure there is not a global variable for support that information. But maybe clever browsers such as Firefox or Google Chrome might support something on it. I have made a quick search on net and I came with these.
First, check Mozilla Tab Helper can be work with Mozilla. But be remember, this will never be a cross browser solution. Also, I am thinking there is not a cross browser solution.
Second one is, if you want to use this for your own use then it might bu useful, I don't test it. This is a addon. Here is the Open Tab Count Mozilla Addon
Open Tab Preview