Redirect script.js to script.php - apache

I have some javascript that is generated by PHP. Currently I am including the javeascript in the html using
<script type="text/javascript" src="js/script.php">
But I want to use
<script type="text/javascript" src="js/script.js">
Now script.js does not exist, but I want it to redirect to script.php without the user knowing.
Can this be done with .htaccess?

If your web server supports mod_rewrite, you could do something like this:
RewriteEngine On
RewriteRule ^js/script\.js$ js/script.php
If you have more than one script, you could generalize that RewriteRule by using a backreference from the test pattern:
RewriteRule ^js/(.*)\.js$ js/$1.php

In the parent directory you could have a .htaccess which maps all asset files to the relevant php file.
RewriteEngine on
RewriteRule ^js/(.*)\.js$ js/$1.js.php
RewriteRule ^css/(.*)\.css$ css/$1.css.php
notice I have kept the file extension for better readability.
Files
htdocs
mysite
assets
.htaccess
js->
script.js.php ( http://locahost/mysite/assets/js/script.js )
css->
style.css.php ( http://locahost/mysite/assets/css/style.js )
Headers
By default the files will be outputted as php, you will have to change the content type header to the correct type(js,css,txt,xml, etc).
You might also want to disable the files from being cached as they most probably change frequently.
You can either do this in all the php files or in the .htaccess file.
PHP
content type
js/*.js.php -> header("Content-type: text/javascript");
css/*.css.php ->header("Content-type: text/css");
cache
*.php -> header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1.
*.php -> header('Pragma: no-cache'); // HTTP 1.0.
*.php -> header('Expires: 0'); // Proxies.
.htaccess
content type
<FilesMatch \.js.php$>
Header set Cache-Control "no-transform"
Header set Content-Type "application/javascript; charset=utf-8"
</FilesMatch>
<FilesMatch \.css.php$>
Header set Cache-Control "no-transform"
Header set Content-Type "text/css; charset=utf-8"
</FilesMatch>
cache
<IfModule mod_headers.c>
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires 0
</IfModule>

If you just want your script src to end in ".js" you could always leave it as a .php file and link it in like this:
<script type="text/javascript" src="js/script.php?name=script.js">
This technique is commonly used with php or other scripts which generate images:
<img src="images/thumbnailer.php?x=foo.jpg">
This way if the browser tries to determine the type of file by the "extension," it will be "tricked" into using the right format.

Related

No cache HTML file apache Centos7 (VueJS / Quasar Build)

We've build an application with vueJs using Quasar Framework
But after each rebuild (with quasar build command executed by a gitlab runner) our main index.html file isn't reload properly by client's browser (seems it's more chrome than other browser who's keeping the index.html in cache)
In our application we have many css and js file named like that for example :
app.34456435fdfe.js
vendor.4325gfd.js
runtime.ksdj424.js
The app file js and the runtime file js change properly but the older version still stay in cache client browser loaded because the index.html version loading those files isn't the last (but those store in the cache browser)
I explain :
First build make an app.0000000.js (for exemple) and a runtime.0123456.js
The second make an app.000001.js and a runtime.654321.js
But the two first version still loading in broswer (due to the index.html file cached) so the client is stuck on a white page (because app.0000000.js still not exist it return an 404)
How can we force to clear the cache ?
In the index.html file of quasar we’ve adding this :
<meta http-equiv=“cache-control” content=“no-cache, no-store, private, must-revalidate, post-check=0, pre-check=0”>
<meta http-equiv=“cache-control” content=“max-age=0”>
<meta http-equiv=“expires” content=“0”>
<meta http-equiv=“expires” content=“Tue, 01 Jan 1980 1:00:00 GMT”>
<meta http-equiv=“pragma” content=“no-cache”>
We have an .htaccess too with :
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType text/html M0
</IfModule>
<IfModule mod_headers.c>
<filesMatch "\.(html|htm|js|css)$">
FileETag None
Header unset ETag
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires 0
</filesMatch>
Header unset ETag
Header unset Last-Modified
</IfModule>
And in the httpd.conf file we have added this :
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType text/html M0
</IfModule>
It's seems working properly on Safari and Firefox but on chrome we still have "Loaded from disk cache"
Chrome debug tool
More debug tool
Header properly set
This issue we're facing is a real problem, we will use service-worker in few weeks but we need a solution for clearing cache properly until we develop SW (no caching html will be better)
Thanks ! (And sorry for my english)
NB :
I've tried that : How to control web page caching, across all browsers?
And that : VueJS/browser caching production builds (similar problem)

How to disable caching of a rewrite rule which proxies an internal server?

I'm using an htaccess rule to proxy to an internal server, using the answer recommended on this question, "Can ProxyPass and ProxyPassReverse Work in htaccess". I'm using htaccess as that is all I have access to. The method suggested works, but when I make a change on one of the internal pages and reload (from the external server) I don't even see it hitting the internal server, even after clearing the cache on the browser. In fact, if I try to load the page from another browser which never has tried to load the page before, it too gets the old copy.
This suggests something is being cached on the server, but how to change this? The apparent caching is rather annoying as I am trying to fix some issues that only occur on the proxied page.
If I hit the internal server directly and reload after a change, I always get the latest page.
I have tried a <filesMatch ...> rule for the affected pattern (using the same pattern as used in the RewriteRule in the following manner:
<filesMatch "^/?somedir/(.*)$">
Header set Cache-Control "max-age=0, private, no-store, no-cache, must-revalidate"
</filesMatch>
My rewrite rule looks like this, and comes after the filesMatch directive:
RewriteEngine On
RewriteRule ^/?somedir/(.*)$ https://internal.local.net:8000/$1 [L,P]
But this has not had any effect. I have also tried "NoCache *" but this directive causes an error as it is not allowed in an .htaccess file.
The P-flag in your RewriteRule causes the request to be proxied to the internal server using mod_proxy. mod_proxy by itself does not cache content. The caching is probably a result of mod_cache being enabled as well on the server. The settings you need to disable caching for your internal server can unfortunately only be done in server or virtual-host config. The solution would be to add what you tried to the configuration of the internal server thus telling mod_cache that it should not cache any response from your internal server:
Using .htaccess
Header set Cache-Control "max-age=0, private, no-store, no-cache, must-revalidate"
or PHP
header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1.
header('Pragma: no-cache'); // HTTP 1.0.
header('Expires: 0'); // Proxies.
Try adding this in an htaccess file in your "somedir" directory:
ExpiresActive On
ExpiresDefault "now"

Exclude directory from browser caching with .htaccess

I have a .htaccess file that handles the browser caching. I set the rules with file extensions. How can I modify the following snippet to exclude a specific directory from the browser caching?
<FilesMatch "\.(gif|png|jpg|js|css|ico|woff|eot|svg|ttf)$">
Header set Cache-Control "max-age=2592000, public, must-revalidate"
Header unset Last-Modified
</FilesMatch>
I there any way to totally forbid the caching in this directory?
You can try to overwrite parent cache function. Just replace another htaccess file under desired folder and set to cache for 1 sec. Worked for me.
ExpiresActive On
ExpiresDefault A1
Header append Cache-Control must-revalidate

htaccess mod_headers for no-caching

We have an application that allows users to add/edit/replace/delete content (text, images, swfs, mp3s, etc). We want the admins to always have the latest updated files by using a no-cache header and when a user runs the application, everything gets/uses the cache.
I have looked into solutions and have tried using html meta tags like:
<meta http-equiv="expires" content="0" />
<meta http-equiv="cache-control" content="no-cache, no-store" />
<meta http-equiv="pragma" content="no-cache" />
But that doesn't seem to be a good solution as this happens after the headers are created and doesn't change the media (images, swfs, mp3s, etc) headers.
I wanted to use apache to set the headers and came across this code for this site:
<filesMatch "\.(html|htm|js|css)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>
</filesMatch>
This seems to be a great solution, however the only real difference between when we need it cached and when it shouldn't be cached is the URL (preview.jsp vs run.jsp), so we can't match it by file type as most files are the same.
Does anyone have a good solution for this type of scenario?
Thanks.
EDIT:
Preview.jsp and run.jsp basically are the same only with different jsp and js processing. They read in the same content and media through an iframe. For example, they each look like:
<%
//Some JSP
%>
/* HTML Headers, JS, ETC */
<iframe id="contentFrame" seamless="1" src="http://somedomain.com/template.html"></iframe>
/* End HTML */
preview.jsp and run.jsp appear in the same directory and use all the same resources. I am looking for a solution to have preview.jsp not to cache anything and run.jsp to cache things.
Server is setup with Apache Tomcat.
A combination of SetEnvIf and Header might do the trick:
# Image, CSS and JavaScript requests normally contain the Referer header
# which tells apache which page is requesting the resource
# Use SetEnvIf directive to set a flag for internal uses
SetEnvIf Referer preview\.jsp force_no_cache
# Header directive optionally accepts env= argument
# If present, the directive is fired if the flag is set
Header unset ETag env=force_no_cache
# repeat for other headers
You can set up corresponding headers in your Java servlet. Apache mod_headers is mostly supposed to work for static resources, managed by Apache. While everything that is provided by application servers is managed on the AS side.
Usually, you can use Filters for this purpose. Here is an example: http://www.tidytutorials.com/2009/11/adding-headers-to-requests-in-filters.html

Setting a filename inside the header with htaccess

we have an application which downloads the files from the server. After the download them it needs to save it, for that it uses the filename paramter which is comming from the responce header.
When i'm using the standart PHP download.php?id=downloadID i can set the headers with no problem.
The task now is that on the client server they do not have any php available,
i need to set the filename inside of the responce header.
here is the htaccess what i have:
<FilesMatch "\.(?i:pdf)$">
Header set Content-Type: application/octet-stream
Header set Content-Disposition: "attachment; filename=FILE_NAME.pdf"
</FilesMatch>
And i have no idea how to parce the file name dynamicaly to the header using htaccess.
I've google it looked for it but still no solution.
Any suggestions?
I have no idea if it works, but this would be my first attempt.
RewriteRule [^/]+\.pdf$ - [E=FILENAME:$0]
<FilesMatch "\.(?i:pdf)$">
Header set Content-Type application/octet-stream
Header set Content-Disposition "attachment; filename=%{FILENAME}e"
</FilesMatch>
EDIT Seems some apache installs prefix the env variable with REDIRECT_
RewriteRule [^/]+\.pdf$ - [E=FILENAME:$0]
Header set Content-Type application/octet-stream env=REDIRECT_FILENAME
Header set Content-Disposition "attachment; filename=%{REDIRECT_FILENAME}e" env=REDIRECT_FILENAME
Above code doesn't work out of the box. In my case, I needed another internal redirect.
But why would you need to set the filename in the header if the request URL contains the filename too? All browsers will save the file with under the name in the URL. So going to /path/test.pdf will result in browsers suggesting the filename test.pdf.