CSS/JS中的动态URLs

14

我正在拆分一个较大的应用程序,并引入一个“cdn” URL来存放常见对象,例如CSS、javascript和图像,以避免重复。但是,我需要为我们的开发环境拥有单独的URL,因此我可能会有:

http://cdn-dev.example.com
http://cdn-qua.example.com
http://cdn.example.com

根据我们所使用的环境而定。我可以让这个东西在我们PHP代码生成的内容中运行,但我对于将被调用的.css和.js文件感到茫然。例如,我该如何做出类似这样的东西:

.cool-button { background-image: url('http://cdn.example.com/images/button.png'); }

如何在不同的域名之间切换?

最好的方法是什么?

[编辑]

为了让大家清楚,CDN地址是一个与网站不同的域名。因此,开发站点可能是 http://www-dev.domain.com,它将使用 http://cdn-dev.domain.com

9个回答

26

使用相对路径而不是绝对路径。当在CSS文件内部时,路径是相对于CSS文件而不是HTML页面。

如果你的CSS文件在这里

http://cdn.example.com/css/style.css

而你的类是

.cool-button { background-image: url('../images/button.png'); }

接下来,浏览器将尝试从

http://cdn.example.com/images/button.png

通常我会将图像文件夹放在CSS主题文件夹下,因为这样可以使用与特定样式表文档无关的图像名称。例如,我可以在/this_theme/和/that_theme/下都有一个button.png文件,并且类定义可以保持不变。 - great_llama
不要混淆相对/绝对URI路径和绝对/相对URIs。因为/css/style.css是一个绝对URI路径,但是是一个相对URI。而以http://cdn.example.com/css/style.css开头的URI是一个绝对URI,但不是一个URI路径(它只包含一个URI路径)。 - Gumbo
2
当然,这仅适用于您将CSS文件托管在与图像完全相同的域上的情况,但通常并非如此。 - travis-146
1
为什么要将与样式表相关的图像托管在CDN上,而不是样式表本身? - great_llama

6
只使用相对于域名的URL吗?
.cool-button { background-image: url('/images/button.png'); }

那么浏览器将会在当前域名下进行查找。

2

根据您的服务器配置,您还可以在文件名后追加 .php 扩展名,并将其视为 PHP 脚本:

I.E.: style.css.php would contain:

.cool-button { background-image url(<?php echo $bgImgUrl;?>); }

这也适用于JavaScript文件。

2
你还可以拥有一个构建过程并使用模板生成特定于环境的文件,例如在名为yoursite.template.css的文件中:
.cool-button { background-image: url('@@URL@@/images/button.png'); }
创建yoursite.css文件,然后将@@URL@@替换为所需的域名。

1

我今天刚好在做同样的事情,这是我的解决方案。

将以下代码添加到您网站根目录下的 .htaccess 文件中。这需要 Apache 和 Mod_rewrite 的支持。

RewriteEngine on
RewriteBase /

# Redirect content to the CDN

RewriteCond %{HTTP_HOST} !^cdn\.server\.com$    [NC]
RewriteRule .*\.(jpg|gif|png|flv|css|js|swf)$   http://cdn.server.com/$0    [R=301,L]

这将把括号中的文件类型请求发送到您的 CDN ,并将其他类型的请求保留在您的主服务器上。

这不是违背CDN的初衷吗?这意味着客户端每次请求CDN都还需要与你的服务器进行联系,而不是直接访问CDN。 - davr
是的,但内容不会从您的服务器提供。因此,不会从您的服务器传递5Mb FLV。它将被重定向到CDN,实际下载将在那里发生。这种配置使您可以轻松地从单个服务器开发环境切换到实时环境,而无需进行任何更改。我并不认为这是唯一的方法。这对我来说很有效,301的微小往返值得。 - Greg B
如果您的一些文件在CDN上,而另一些文件在本地,那么这将如何工作? - dragonmantank
这并不一定适用于所有情况,只是我遇到的一个例子。 - Greg B

1
寻找答案时,我看到了一个简单的方法:创建带有重复类的CSS文件,一个用于场景1(图像从同一域加载),另一个用于场景2(图像从CDN加载)。
例如:
.container {background-image:url(my/site/image.png;)}
.container-CDN {background-image:url(http://my.site.cdn.com/image.png;)}

然后在您的index.php文件中,使用PHP调用正确的类

例如:

<body class="container<?PHP if ($whatever) {echo "-CDN";} ?>">

我最喜欢这个,谢谢你的提示。使用Sass应该很容易。 - TWilly

0

嗯...我想出来的解决方案有点...hackish、丑陋和愚蠢。但是,它起作用了:

<?php
    if ($_SERVER['SERVER_NAME'] == "www.domain.tld") {

        $incs_path  = "/usr/local/psa/home/vhosts/domain.tld/non-web-root-folder/private-files";

    }
    else {
        $incs_path  = "incs";
    }

require_once "$incs_path/$file-to-be-called.inc";

?>

正如所述,这是一种粗糙且丑陋的方法,可以更加优美地完成。但至少它允许您根据主机定义特定文件组的特定位置。


相对于域名的 URL 可能更美观、更实用。我的建议是为了链接到其他私密信息(我倾向于将这种东西用于 Web 应用程序中的数据库密码等)。 - David Thomas

0
如果服务器相同,您可以使用相对路径。例如 /http/blah/test/images/button.png 或 ../images/button.png。

0

1
但这也有一些不利之处。例如,只使用片段标识符 foo 的URI引用将被解析为 /#foo 而不是同一文档中的 #foo - Gumbo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接