【问题标题】:Serving static content from dynamic URLs从动态 URL 提供静态内容
【发布时间】:2013-07-23 03:51:49
【问题描述】:

我一直在到处搜索,试图找到一种解决方案来从不同的子目录中提供静态内容。这就是我的意思。所有静态内容位于:

/usr/share/nginx/www/www.example.com/skin/

图片、JavaScript 库和样式表:

/usr/share/nginx/www/www.example.com/skin/css/

/usr/share/nginx/www/www.example.com/skin/img/

/usr/share/nginx/www/www.example.com/skin/js/

css、img 和 js 这些目录中的每一个都有许多其他子目录。

问题: 如果您查看我的服务器配置,您会看到所有请求都由 index.phtml 处理,其中包括 autoloader.php 以根据请求的 URI 动态加载适当的内容。

我面临的问题是动态 URL 无法加载具有相对路径的静态内容:

即JavaScript 库的相对路径:skin/js/library/helloWorld.js

这有效: https://www.example.com/skin/js/library/helloWorld.js

这不起作用:

https://www.example.com/foo/skin/js/library/helloWorld.js

https://www.example.com/foo/bar/skin/js/library/helloWorld.js

由于 URL 是完全动态的,我需要能够在 /skin/{...} 之前使用任意数量的子目录提供静态内容

https://www.example.com/{任意数量的动态子目录}/skin/js/library/helloWorld.js

我的问题: 是否可以修改 $uri 以省略 {any number of dynamic sub-directories} 并将从 /skin/{...} 开始的所有内容重写为 https://www.example.com/skin/{...} ?

location ^(.*)/skin/(.*)\.(jpeg|jpg|gif|png|ico|svg|css|js)$ {
    # Something like:
    # rewrite ^ https://www.example.com/skin/{requested static content} break;
    # or 
    # try_files /skin/{requested static content};
}

我的服务器配置:

server {
    listen 80;
    server_name example.com www.example.com;
    rewrite ^ https://www.example.com$uri permanent;
}

server {
    listen 443 default_server ssl;

    add_header Strict-Transport-Security max-age=31536000;
    add_header X-Frame-Options SAMEORIGIN;

    root /usr/share/nginx/www/www.example.com;
    index index.phtml;

    server_name example.com www.example.com;

    if ($host !~* ^www\.) {
        rewrite ^ https://www.example.com$uri permanent;
    }

    location ^~ /autoloader.php {
            deny all;
    }

    location / {
            try_files $uri $uri/ /index.phtml;
    }

    error_page 500 502 503 504 404 403 /error.phtml;
}

可能的解决方案

这些是我想避免的解决方案:

  • 使用绝对路径链接静态内容。 (对域名不好 变化)
  • 在我的服务器中为 /skin/ 中的每个子目录添加 location 配置。 (非动态)
  • 在我的内部解析静态内容请求 索引.phtml。 (看起来很乱……)

抱歉,帖子太长了。我只是想澄清一下我的情况。谢谢大家!

【问题讨论】:

  • 我不太明白为什么不能直接从你的index.html请求像“/skin/js/library/helloWorld.js”这样的url,当域改变时它不会受到影响。这意味着在webroot中请求文件。

标签: nginx


【解决方案1】:

TIL:咖啡和短暂的休息可以创造奇迹哈哈。

对于可能遇到此帖子并寻找相同答案的每个人来说,这是一个解决方案。

当使用相对路径链接静态内容时,即 HTML 页面中的图像:

<img src="skin/img/helloWorld.jpg" />

位于 index.html 中并从 https://www.example.com 引用,图像将正确加载,因为相对路径将附加到 URL 的末尾,如下所示:

https://www.example.com/skin/img/helloWorld.jpg

但是如果我们将索引移动到一个子目录,比如:

https://www.example.com/sub-directory/index.html

图像不会加载,因为请求如下所示:

https://www.example.com/sub-directory/skin/img/helloWorld.jpg

由于我们的skin 目录位于下一级,因此请求将导致 404。

解决方案

要正确引用任何子目录中的静态内容,就像在前面的示例中一样:

https://www.example.com/sub-directory/category/post/id/index.html

使用/skin/img/helloWorld.jpg作为相对路径:

<img src="/skin/img/helloWorld.jpg" />

相对路径开头的/ 表示从您的Web 目录的ROOT 开始,然后尝试从那里找到正确的文件。在这种情况下,无论 index.html 位于何处,无论是 10 个目录深,图像的路径都将始终如下所示:

https://www.example.com/skin/img/helloWorld.jpg

所以请记住相对路径:skin/img/helloWorld.jpg 和 /skin/img/helloWorld.jpg 处理方式不同。

【讨论】:

  • 我刚刚注意到您对我的问题的评论,并且您一直都有解决方案。你是 100% 正确的。谢谢特洛伊!
  • 当一个 URL 以 / 开头时,这意味着这是相对于根域的,所以如果你在 http://example.com/a/b/c/d/e... 内调用 /images/img.jpg 没关系,它总是相对于域:http://example.com/images/img.jpg,但没有前导 /,它将相对于当前 URI:http://example.com/a/b/c/d/e/images/img.jpg,编辑:好的,我刚刚意识到你已经写过:D跨度>
【解决方案2】:

将静态文件请求重写到正确的目录,例如:

location ^(.*)/skin/(.*)\.(jpeg|jpg|gif|png|ico|svg|css|js)$ {
    rewrite "^.*/skin/(.*)$" /skin/$1 break;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多