如果(缓存)文件存在,则设置CORS标头

时间:2018-11-05 11:37:19

标签: apache .htaccess http-headers

我具有以下.htaccess配置,可将用户重定向到API响应的缓存版本:

RewriteCond %{REQUEST_METHOD} GET
RewriteRule ^(.*)?/$ - [E=URL:$1]
RewriteCond %{DOCUMENT_ROOT}/cache/%{ENV:URL}.json -f
RewriteRule ^(.*) %{DOCUMENT_ROOT}/cache/%{ENV:URL}.json [L]

URL环境变量设置为考虑可能存在或可能不存在的尾部斜杠。这部分工作正常,并且可以完成应有的作用。

但是,由于请求是通过AJAX调用发出的,因此我们需要为这些情况设置CORS标头。如果没有缓存的响应,则不要设置这些标头,这一点很重要。

我尝试了以下操作,但是没有用。

使用If块:

RewriteCond %{REQUEST_METHOD} GET
RewriteRule ^(.*)?/$ - [E=URL:$1] [PC]

<If "-f '%{DOCUMENT_ROOT}/cache/%{ENV:URL}.json'">
    Header set Access-Control-Allow-Origin "*"
    Header set Access-Control-Allow-Headers "Content-Type,Accept"
    Header set Access-Control-Allow-Methods "GET,POST,PUT,DELETE,OPTIONS"
    Header set Access-Control-Expose-Headers "Content-Type,Content-Length"
</If>

使用setEnvIfExpr

RewriteCond %{REQUEST_METHOD} GET
RewriteRule ^(.*)?/$ - [E=URL:$1] [PC]

setEnvIfExpr "-f '%{DOCUMENT_ROOT}/cache/${ENV:URL}.json'" USE_CACHE

Header set Access-Control-Allow-Origin "*" env=USE_CACHE
Header set Access-Control-Allow-Headers "Content-Type,Accept" env=USE_CACHE
Header set Access-Control-Allow-Methods "GET,POST,PUT,DELETE,OPTIONS" env=USE_CACHE
Header set Access-Control-Expose-Headers "Content-Type,Content-Length" env=USE_CACHE

请注意,在两种情况下,如果我用存在的硬编码文件替换%{ENV:URL},则头文件将按照上一个示例中的预期设置。

由于某些原因,在这些条件表达式中%{ENV:URL}不可用?

我已经尝试了很多事情,但似乎没有一件事情能解决这个琐碎的事情。

请帮助!

谢谢!

1 个答案:

答案 0 :(得分:0)

我们刚刚设法解决了这个问题。

显然,mod_rewrite和mod_headers是两个单独的模块,它们以“错误”的顺序运行,以使上述代码正常工作。

这是我们为其他需要此解决方案的人解决的问题:

# Redirect to a cached version of the resource if its available.
RewriteCond %{REQUEST_METHOD} GET
RewriteRule ^(.+)$ - [E=MY_CACHED_URL:%{DOCUMENT_ROOT}/cache/$1.json]
RewriteRule ^(.+)/$ - [E=MY_CACHED_URL:%{DOCUMENT_ROOT}/cache/$1.json]
RewriteCond %{ENV:MY_CACHED_URL} -f
RewriteRule ^(.*) %{ENV:MY_CACHED_URL} [L]

# Set CORS headers for cached results.
SetEnvIfExpr "%{REQUEST_URI} =~ m#/cache/.+#" IS_CACHED=1
Header set Access-Control-Allow-Origin "*" env=IS_CACHED
Header set Access-Control-Allow-Headers "Content-Type,Accept" env=IS_CACHED
Header set Access-Control-Allow-Methods "GET,POST,PUT,DELETE,OPTIONS" env=IS_CACHED
Header set Access-Control-Expose-Headers "Content-Type,Content-Length" env=IS_CACHED