【问题标题】:Can I set an Access-Control-Allow-Origin header to all pages on a domain and its subdomains?我可以为域及其子域上的所有页面设置 Access-Control-Allow-Origin 标头吗?
【发布时间】:2014-07-16 08:02:22
【问题描述】:

我正在尝试使用法律允许我使用但不分发的网络字体。我将字体文件托管在用于静态内容的单独域上。这两个域是不相关的(一个不是另一个的子域)。假设使用 webfont 的站点是 example.com,托管它的站点是 example.net

我在example.net上的.htaccess 文件中尝试了这个

<FilesMatch "\.(ttf|otf|eot|woff|svg)$">
  <IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "example.com"
  </IfModule>
</FilesMatch>

但是,这使得字体只能在example.com 的主页上工作。我又试了一次:

    Header set Access-Control-Allow-Origin "example.com/*"

现在字体可以在example.com 除主页之外的所有地方使用,这(当然)不是我想要的。

我找不到此标头的任何文档。我真正想要的是允许example.comwww.example.com 上的所有页面(或者,为了更好的衡量标准,*.example.com)。有没有一种简单的方法可以做到这一点?我猜标题需要某种正则表达式。

寻找我找到的文档,

  • 很多关于此标头如何与 ajax 交互的内容,
  • 很多简短的说明说 webfonts 是必需的(至少在 Firefox 中)。

我没有找到任何有关标头本身语法或如何指定域变体的文档。

基于an answer to a related question,我尝试了这个:

<FilesMatch "\.(ttf|otf|eot|woff|svg)$">
    <IfModule mod_headers.c>
        SetEnvIf Origin "http(s)?://(www\.)?(example.com)$" AccessControlAllowOrigin=$0$1
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
        Header set Access-Control-Allow-Credentials true
    </IfModule>
</FilesMatch>

我的理解是,这将为每个请求设置一个单独的标头,允许每个请求页面单独使用该字体。但是,通过 Firebug 进行检查,无论是在主页上还是在其他地方,看起来标题始终是 http://example.com。尽管如此,这可行,但让我感到困惑。一个相关问题显示a similar setup was not working for someone else。他的问题表明,对他而言,它实际上 为每个请求页面发送不同的标头,因此 HTTP 304 Not Modified 响应会中断。他的解决方案是在.htaccess 中添加一个always 指令,但对我来说这会导致HTTP 500 错误。

就像现在一样,它正在工作,我认为example.com 切换到 HTTPS 时会继续工作(很快就会如此)。但是,我不禁觉得它过于复杂。它每次都设置相同的标题,但使用复杂的模式匹配来做到这一点。另外,虽然我对HTTP 304 Not Modified 的响应还没有任何问题(事实上,我还没有看到任何这样的响应:浏览器根本不会请求字体文件,直到我清除缓存),我担心我可能会在未来看到他们。

【问题讨论】:

  • “就像现在一样,它正在工作”——那么,问题到底是什么?另见stackoverflow.com/questions/14003332
  • "它每次都设置相同的标头,但是使用复杂的模式匹配来做到这一点。"另外,当我实际上要求它每次都设置相同的标题时,它不起作用。

标签: http-headers cross-domain webfonts


【解决方案1】:

正如CORS spec 所述,Access-Control-Allow-Origin 标头(或*null)中只能有一个域。

所以是的,您需要根据请求站点的域来设置不同的标头。这就是为什么您发布的 apache config sn-p 尝试将请求的 Origin 标头与此 regex 匹配:

http(s)?://(www\.)?(example.com)$

$ 匹配字符串的结尾。因此,此正则表达式将匹配来自 http://www.example.comhttp://example.com 及其 https 等价物的请求,但不匹配 example.com/bla。这应该没问题,因为请求的Origin 标头以及响应should containAccess-Control-Allow-Origin 标头仅是主机而不是子页面。

因此,当您在页面http://example.com/about-us 上时,浏览器将发送类似以下请求以从http://cdn.net/myfont.otf 获取字体:

GET /myfont.otf HTTP/1.1
Host: http://cdn.net
Origin: http://example.com

服务器将在 Origin 标头上进行模式匹配并返回:

Access-Control-Allow-Origin: http://example.com

【讨论】:

  • 好的。这回答了为什么当我明确设置 example.com 时它不起作用:它需要协议。它解释了为什么模式匹配是必要的。在没有协议的情况下发生的怪异(字体只在主页上工作,或者除了主页以外的任何地方)可以归结为面对不准确的标题时浏览器的怪癖。谢谢。
【解决方案2】:

作为参考,我出于同样的目的更新了 /etc/apache2/conf/sites-enabled/* 文件。我的代码:

AllowOverride FileInfo 选项 标头集 Access-Control-Allow-Origin "http://example.com" 标头集 Access-Control-Allow-Origin "http://www.example.com" 目录>

我必须处理的一件事 - 我没有启用 mod_headers,因此重新启动 apache 失败。我必须启用它

a2enmods 标头

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-03
    • 2013-12-02
    • 2015-07-18
    • 2011-07-28
    • 2016-07-21
    • 2018-09-29
    • 1970-01-01
    • 2018-01-24
    相关资源
    最近更新 更多