Nginx无法加载CSS文件。

118

我最近决定从Apache2切换到Nginx。我在我的CentOS服务器上安装了Nginx并设置了基本配置。当我尝试在浏览器(FF/Chrome)中加载我的站点时,我注意到CSS文件未加载。我检查了错误控制台,并看到了这个消息:

错误:样式表http://example.com/style.css未加载,因为它的MIME类型“text/html”不是“text/css”。

我检查了Nginx配置,一切似乎都很好:

http {
    include /etc/nginx/mime.types;
    ..........
}

在 /etc/nginx/mime.types 中正确设置了 css 文件的 MIME 类型。

text/css css;

一切似乎都已经配置好了,但我的 CSS 文件仍然无法加载。我无法解释这种情况。

另外值得一提的是,最初我使用 epel 存储库安装了 Nginx,并且获得了一个旧版本:0.8... 看起来我的问题是由于该版本中存在的一个 bug 所导致的,因此我卸载了 0.8 版本,将 nginx 存储库添加到 yum 中,然后安装了最新版本:1.0.14。我以为新版本会解决我的问题,但不幸的是它没有,所以我想不出更多办法。

非常感谢任何帮助。

配置文件:

/etc/nginx/nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

/etc/nginx/conf.d/default.conf

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    location / {
         root    /usr/share/nginx/html;
         index  index.html index.htm index.php;
         fastcgi_pass   127.0.0.1:9000;
         fastcgi_index  index.php;
         fastcgi_param  SCRIPT_FILENAME  /usr/share/nginx/html$fastcgi_script_name;
         include        fastcgi_params;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

/etc/nginx/mime.types

types {
    text/html                             html htm shtml;
    text/css                              css;
    text/xml                              xml;
    image/gif                             gif;
    image/jpeg                            jpeg jpg;
    application/x-javascript              js;
    application/atom+xml                  atom;
    application/rss+xml                   rss;
    ..........................................
    other types here
    ..........................................
}

请粘贴您的配置代码。通常情况下,您已经处理了其他类型的文件,但是跳过公共文件部分会导致类似CSS和图像等资源返回404错误,或者在您的情况下,MIME类型错误。 - Kristian
1
对于我的情况,你的问题成为了答案。干杯。 - Vassily
17个回答

142
include /etc/nginx/mime.types; 放在 location / { 下面,而不是 http { 下面,这对我解决了问题。

3
请注意,如果您从头开始配置(除了 MIME 类型之外),那么 include mime.types; 就能够发挥作用,因为它(至少在 Windows 上的 nginx 1.5.2)只是相对于其他配置文件而言。 - omilke
26
请注意,您应该完全刷新网站,例如使用 Ctrl+F5 键进行刷新,以避免获取具有错误标头的缓存文件。 - CarelZA
1
这确实有效,但为什么?在http中应该足够了!事实上,在开发机器上已经这样运行了一年多,今天它突然停止工作,而且没有进行任何更改(没有nginx更新,甚至没有重新启动)。 - upsfeup
我成功地将 include 放在了 http 里面,如下所示:include mime.types;。详情请见 https://gist.github.com/nishantmodak/d08aae033775cb1a0f8a。 - edan

50

我在网上找到了一个解决办法。我在 /etc/nginx/conf.d/default.conf 中添加了以下内容:

location ~ \.css {
    add_header  Content-Type    text/css;
}
location ~ \.js {
    add_header  Content-Type    application/x-javascript;
}

现在的问题是我的CSS文件请求没有正确重定向,似乎根路径未正确设置。在error.log中我看到:

2012/04/11 14:01:23 [error] 7260#0: *2 open() "/etc/nginx//html/style.css"

所以作为第二个解决方案,我添加了每个定义位置的根路径。现在它可以工作,但感觉有点冗余。难道根路径不是从 / 位置继承的吗?


2
这是一个nginx的bug吗?这是我让它工作的唯一方法。顺便说一句,我正在使用Arch Linux,nginx 1.4.1-3版本。 - tprk77
@tprk77 不是一个 bug,被接受的答案只是一个解决方法,如果想要一个正确的解决方案,请看我的回答 https://dev59.com/f2kw5IYBdhLWcg3wMHkY#23282158 - zamnuts

27

location /指令实际上是通过fastcgi处理style.css文件的。因此,提供文件的是fastcgi(nginx > fastcgi > filesystem),而不是文件系统本身(nginx > filesystem)。

由于某种我还没想明白的原因(肯定有某个指令),NGINX会将从fastcgi提供的所有内容应用mime类型text/html,除非后端应用程序明确说明了其他情况。

罪魁祸首是这个具体的配置块:

location / {
     root    /usr/share/nginx/html;
     index  index.html index.htm index.php;
     fastcgi_pass   127.0.0.1:9000;
     fastcgi_index  index.php;
     fastcgi_param  SCRIPT_FILENAME  /usr/share/nginx/html$fastcgi_script_name;
     include        fastcgi_params;
}

应该是:

location ~ \.php$ { # this line
     root    /usr/share/nginx/html;
     index  index.html index.htm index.php;
     fastcgi_split_path_info ^(.+\.php)(/.+)$; #this line
     fastcgi_pass   127.0.0.1:9000;
     fastcgi_index  index.php;
     fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name; # update this too
     include        fastcgi_params;
}

此更改确保仅从fastcgi请求*.php文件。此时,NGINX将应用正确的MIME类型。如果您有任何URL重写,请在location指令(location ~\.php$)之前处理它,以便正确的扩展名被派生并正确路由到fastcgi。

请务必查看此文章,了解使用try_files的其他安全注意事项。考虑到安全问题,我认为这是一种功能而不是漏洞。


1
这应该是被接受的答案,另请参阅:http://forum.nginx.org/read.php?2,155222,155261#msg-155261 - Alfred Bez
1
看起来这仍然是一个问题,距离最初的问题已经过去了4年以上。如果您只提供静态内容,即没有PHP,正确的配置应该是什么样子的? - rob

12
我也遇到过这个问题。直到我意识到问题所在,它一直让我感到困惑:

你有这个:

include       /etc/nginx/mime.types;
default_type  application/octet-stream;
你需要这个:

default_type  application/octet-stream;
include       /etc/nginx/mime.types;

nginx似乎存在一个bug或文档缺陷(这可能是预期的行为,但仍有些奇怪)。


7
  1. In your nginx.conf file, add mime.types to your http body like so:

    http {
        include /etc/nginx/mime.types;
        include /etc/nginx/conf.d/*.conf;
    }
    
  2. Now go to the terminal and run the following to reload the server:

    sudo nginx -s reload
    
  3. Open your web browser and do a hard reload: Right click on the reload button and select hard reload. On Chrome you can do Ctrl+Shift+R


这些声明已经在原始帖子的配置文件中了。 - undefined

6
我将从其他答案中获取的一些建议进行整理,并发现这些奇怪的操作有所帮助(至少对我来说是这样的)。
1)我在服务器块中添加了以下内容:
location ~ \.css {
 add_header Content-Type text/css;
}

我重新加载了nginx,然后在error.log中得到以下错误:

2015/06/18 11:32:29 [error] 3430#3430: *169 open() "/etc/nginx/html/css/mysite.css" failed (2: No such file or directory)

2) 我删掉了这些行,重新加载nginx,然后样式表就可以正常工作了。 我无法解释发生了什么,因为我的配置文件变成了与之前相同的状态。

我的情况是在VirtualBox上运行干净的xubuntu 14.04,nginx/1.9.2,在/etc/hosts中有一行127.51.1.1 mysite,以及非常简单的/etc/nginx/nginx.conf配置文件,其中包含一个服务器块:

user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include /etc/nginx/mime.types;

    server {
        listen 80;
        server_name mysite;

        location / {
            root /home/testuser/dev/mysite/;
        }
    }
}

哈哈,和你一样 xD 没有 MIME 类型,添加规则,重新加载,得到 404 错误,删除规则,重新加载,使用正确的 MIME 类型就可以正常工作了... Ubuntu 19.10,Nginx 1.16.1 - Doubidou

3

我也遇到了这个问题,尝试了很多解决方案,但都没有真正解决我的问题。

这是我解决它的方法:

A. 把域名文档根目录(假设我的根目录为/var/www/nginx-demo)的所有权赋予 Nginx 用户(www-data),以避免任何权限问题:

sudo chown -R www-data: /var/www/nginx-demo

B. 确认您的虚拟主机服务器块符合此标准(例如,如果我使用localhost作为我的server_name,并且我的根目录为/var/www/nginx-demo/website

server {
   listen 80;
   listen [::]:80;

   server_name localhost;

   root /var/www/nginx-demo/website;
   index index.html;

   location / {
            try_files $uri $uri/ =404;
   }
}

C. 测试 Nginx 配置文件的正确语法:

sudo nginx -t

如果配置语法没有错误,输出将如下所示:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

D. 重新启动Nginx服务以使更改生效:

sudo systemctl restart nginx

E. 在浏览器中使用键盘组合Ctrl + F5Ctrl + Fn + F5,强制刷新您的网站,以避免缓存了具有不正确标头的文件。

就是这些。

希望能对您有所帮助。


1
对我来说,这是在网页浏览器上安装了广告拦截器。它不允许加载style.css文件。

1
我在Windows中遇到了同样的问题。 我通过在nginx.conf文件的http {下添加include mime.types;来解决它。 然后它仍然不起作用...所以我查看了error.log文件,发现它试图从文件路径中带有/ http文件夹的地方加载.css和javascript文件。例如: 我的.css文件位于:“C:\Users\pc\Documents\nginx-server\player-web\css\index.css” 但它却从这个位置获取: “C:\Users\pc\Documents\nginx-server*html*\player-web\css\index.css” 所以我将我的player-web文件夹更改为html文件夹中的一个,并且它就可以工作了;)

我有完全相同的问题。但是对我来说,移动到html文件夹不是一个选项。您知道为什么它会以/html为前缀吗? - Gurnard
我曾经遇到过类似的问题。你找到解决方案和原因了吗? - iheathers
我遇到了类似的问题,即路径后面附加了/wordpress/。因此,我按照https://wordpress.org/support/article/changing-the-site-url/编辑了wp-config.php文件以解决该问题。 - iheathers

1

我花了很多时间阅读了本页上所有的答案,但没有找到解决方法。后来我偶然改变了目录和子目录的所有者和权限,使用了以下命令。我将 /usr/share/nginx/html 中的 Web 项目目录的所有者更改为root用户:

chown root /usr/share/nginx/html/mywebprojectdir/*

最后,我使用以下命令更改了该目录及其子目录的权限:

chmod 755 /usr/share/nginx/html/mywebprojectdir/*

注意:如果被拒绝,您可以使用sudo


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