In Apache, how can I set a Response Header only if it is not already set by the CGI application?
I need a way to automatically add the Cache-Control header to static content on my website, but I want the CGI application to be able to specify its own Cache-Control header too.
SetEnvIf will not work for this purpose because it only matches Request Headers.
Is there some way to conditionally / optionally set a header if it is not already set?
1) Configure Apache to append the value of empty string ("") to the Cache-Control header to ensure the header is always included in the response.
2) Configure Apache to set the Cache-Control header only if it's still set to empty string.
<FilesMatch "\.(css|ico|flv|gif|jpeg|jpg|js|pdf|png|swf)$">
Header append Cache-Control ""
Header edit Cache-Control "^[, ]*$" "max-age=1800, public"
</FilesMatch>
I want to configure apache for cross-domain access header. I have tried multiple combination as suggested on number of threads on the forum. But its not working for me.
The ways, I have tried:
1) Specify domain on different line as below with Header set :
Header set Access-Control-Allow-Origin "example1.com"
Header set Access-Control-Allow-Origin "example2.com"
Header set Access-Control-Allow-Origin: "example3.com"
With this setup its picking only last one and ignore rest of all.
2) Specify domain on different line as below with Header add :
Header add Access-Control-Allow-Origin "example1.com"
Header add Access-Control-Allow-Origin "example2.com"
Header add Access-Control-Allow-Origin: "example3.com"
With this its showing all three domains in header, but fonts are not getting picked up on Firefox.
3.) Tried Using SetEnvIf, but again its not working :
SetEnvIf Origin "http(s)?://(www\.)?(mydomain.com|mydomain2.com)$" AccessControlAllowOrigin=$0$1
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Finally working with "*", but I don't want to use this.
Please help with this.
For 3 domains, in your .htaccess:
<IfModule mod_headers.c>
SetEnvIf Origin "http(s)?://(www\.)?(domain1.org|domain2.com|domain3.net)$" AccessControlAllowOrigin=$0$1
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header set Access-Control-Allow-Credentials true
</IfModule>
I've tried this and it works for me. Let me know if it doesn't for you.
Unless I'm misunderstanding the manual, it should be:
Header always append Access-Control-Allow-Origin: "example1.com"
Header always append Access-Control-Allow-Origin: "example2.com"
Header always append Access-Control-Allow-Origin: "example3.com"
The manual states that the set and add actions behave in the following way:
set: "The response header is set, replacing any previous header with this name"
add: "...This can result in two (or more) headers having the same name. This can lead to unforeseen consequences..."
To restrict access to certain URIs checkout these docs:
CrossOriginRequestSecurity
Server-Side Access Control#Apache_examples
One helpful trick is to use an Apache rewrite, environment variable, and headers to apply Access-Control-Allow-* to certain URIs. This is useful, for example, to constrain cross-origin requests to GET /api(.*).json requests without credentials:
RewriteRule ^/api(.*)\.json$ /api$1.json [CORS=True]
Header set Access-Control-Allow-Origin "*" env=CORS
Header set Access-Control-Allow-Methods "GET" env=CORS
Header set Access-Control-Allow-Credentials "false" env=CORS
Also, in general, according to W3 Wiki - CORS Enabled#For_Apache
To expose the header, you can add the following line inside Directory, Location, and Files sections, or within an .htaccess file.
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
AND, you can use add rather than set, but be aware that add can add the header multiple times, so it's generally safer to use set.
Try this one, it works for me.
Apply in .htaccess:
SetEnvIf Origin "^http(s)?://(.+\.)?(domain\.org|domain2\.com)$" origin_is=$0
Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is
Will be work 100%, Apply in .htaccess:
# Enable cross domain access control
SetEnvIf Origin "^http(s)?://(.+\.)?(domain1\.com|domain2\.org|domain3\.net)$" REQUEST_ORIGIN=$0
Header always set Access-Control-Allow-Origin %{REQUEST_ORIGIN}e env=REQUEST_ORIGIN
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "x-test-header, Origin, X-Requested-With, Content-Type, Accept"
# Force to request 200 for options
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]
For Apache 2.4, I have used SET command for the Apache web server to set Header dynamically.
<IfModule mod_deflate.c>
# CORS
SetEnvIfNoCase Origin "http(s)?://(\w+\.)?(example.com|localhost)(:[0-9]+)?$" AccessControlAllowOrigin=$0
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header set Access-Control-Allow-Credentials true
</IfModule>
ADD command didn't work for me.
I am using this in my .htaccess file for allowing access to multiple domains
<ifModule mod_headers.c>
SetEnvIf Origin "http(s)?://(localhost:25120|domain.com|domain2.com)$" AccessControlAllowOrigin=$0
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header always set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
</ifModule>
For Multiple domains, in your .htaccess:
<IfModule mod_headers.c>
SetEnvIf Origin "http(s)?://(www\.)?(domain.com|domain.online|domain.in|domain.net|domain.site|domain.website|domain.space)$" AccessControlAllowOrigin=$0
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header set Access-Control-Allow-Credentials true
</IfModule>
it 100% works for me
This works for me in Classic ASP:
If Request.ServerVariables("HTTP_ORIGIN") = "http://domain1.com" Then
Response.AddHeader "Access-Control-Allow-Origin","http://domain1.com"
ElseIf Request.ServerVariables("HTTP_ORIGIN") = "http://domain2.com" Then
Response.AddHeader "Access-Control-Allow-Origin","http://domain2.com"
'and so on
End If
The code below used to be Ok. But now I found that browsers do not cache .php files. Why? MY site is on share host. The host never reply. All the other extention files such as html, js, css, png, are fine cached, besides .php.
Header unset Pragma
FileETag None
Header unset ETag
# 1 YEAR
<filesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|swf|mp3|mp4)$">
Header set Cache-Control "public"
Header set Expires "Thu, 15 Apr 2015 20:00:00 GMT"
Header unset Last-Modified
</filesMatch>
# 2 HOURS
<filesMatch ".(html|htm|xml|txt|xsl|php)$">
Header set Cache-Control "max-age=7200, public"
</filesMatch>
<filesMatch ".(js|css)$">
Header set Cache-Control "public"
Header set Expires "Thu, 15 Apr 2014 20:00:00 GMT"
Header unset Last-Modified
</filesMatch>
Because PHP files can generate different output each time they run, servers don't send cache commands for the output: it might be different next time.
You can force caching by including Cache-control headers in the output generated by PHP, or by specifying the ContentType header from your PHP script.
Which of these is a better approach depends on what your script is doing. Either way, you can implement fine control over caching if your aplication requires it.
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
Despite various measure ments to setup correct caching code in htaccess file, I still get this error:
Specify a cache validator:
All static resources should have either a Last-Modified or ETag header. This will allow browsers to take advantage of the full benefits of caching.
Is there anything wrong with my htaccess caching settings? If you have improvements for these settings i will be very happy to hear. Thank you very much for your suggestions.
<IfModule mod_headers.c>
Header unset Pragma
FileETag None
Header unset ETag
ExpiresActive On
##### DYNAMIC PAGES
<FilesMatch "\\.(ast|php|css)$">
Header set Cache-Control "public, max-age=3600, must-revalidate"
</FilesMatch>
##### STATIC FILES
<FilesMatch "\\.(png|svg|swf|js|xml)$">
Header set Cache-Control "public, max-age=604800, must-revalidate"
Header unset Last-Modified
</FilesMatch>
##### ETERNAL FILES
<FilesMatch "\\.(ico|jpg|gif|ttf|eot|pdf|flv)$">
Header set Cache-Control "public, max-age=7257600, must-revalidate"
Header unset Last-Modified
</FilesMatch>
</IfModule>
You are specifically unsetting the Last-Modified header. That's the cache validator section. Remove those lines that include:
Header unset Last-Modified
Also, is your css really dynamic? CSS can be huge for a lot of websites. Try to cache that just like any other static content.
All static resources should have either a Last-Modified or ETag header. This will allow browsers to take advantage of the full benefits of caching.