为什么 Safari 和其他基于 WebKit 的浏览器无法加载由 Raspberry Pi 4 运行 NGINX 提供的网站?

Why won't Safari and other WebKit-based browsers load site being served from Raspberry Pi 4 running NGINX?

我有一个 Raspberry Pi 4B 运行 Raspberry Pi OS Lite/Debian 11(64 位版本),安装了 NGINX 版本 1.18.0。 NGINX 正在为一个小型(~400KB)网站提供服务,我将路由器设置为将 HTTP 请求转发到 Raspberry Pi。在我的本地网络中,该站点在我尝试过的所有浏览器中都运行良好:Chrome、Edge、Safari 和 iOS 浏览器。

但是,当我尝试通过互联网访问时,Safari 和 iOS 浏览器无法加载整个网站。换句话说,使用 Raspberry Pi 的本地 IP 地址在 Safari 或 iOS 上导航到站点没有问题,但是当我使用站点的域名或路由器的 public IP地址,网站只加载部分,其余超时。该站点在本地和互联网上的 Chrome 和 Edge 中都可以正常加载。

我了解 Safari 和所有 iOS 浏览器都基于 WebKit,并且 Chrome 和 Edge 使用不同的引擎,我觉得这可能是问题的一部分,但是我不知道如何去解决它。我是一个业余爱好者,对网络开发还很陌生。我的目标是从 Raspberry Pi 自行托管一个网站并将其提供给互联网,最好是通过 Safari 和 Chrome。

我在 Stack Overflow 和其他论坛上四处寻找类似的 posts,但没有找到任何解决方案;抱歉,如果我错过了一个,这是多余的 post。我将不胜感激任何见解或参考!该网站使用一些相当简单的 JavaScript 在视图之间进行路由,就像我说的,Safari 在本地呈现它没有任何问题,所以我认为这不是网站资源的问题。也许与 NGINX 有关?不管怎样,让我知道我是否应该提供任何配置细节或类似的东西。谢谢!

对于看到此内容的其他菜鸟:在 NGINX 虚拟主机配置中启用 http/2 似乎有效。 See here 获取简短指南如何操作那。同样,服务器设置为 Raspberry Pi OS Lite/Debian 11(64 位),安装了 NGINX v1.18.0,因此不确定这是否适用于更新版本的 NGINX。这是 sites-available 目录中的我的 NGINX 虚拟主机配置:

server {
        root /var/www/{PATH_TO_SITE_DIST};
        index index.html;
        server_name {SERVER_NAME};

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

        listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot
        listen 443 ssl http2; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/{PATH_TO_SSL_CERT}/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/{PATH_TO_SSL_KEY}/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

        add_header Cache-Control "public, max-age=604800";
        add_header Strict-Transport-Security "max-age=604800; includeSubDomains" always;
        add_header Content-Security-Policy "default-src 'self' https://cdn.jsdelivr.net/";      
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-Frame-Options SAMEORIGIN always;
        add_header X-XSS-Protection "1; mode=block" always;
}

server {
        if ($host = {SERVER_NAME}) {
            return 301 https://$host$request_uri;
        } # managed by Certbot

        listen 80 default_server;
        listen [::]:80 default_server;

        server_name {SERVER_NAME};
        return 404; # managed by Certbot
}

配置包括由 Certbot 管理的 HTTPS/SSL,并设置了多个响应 headers,但 与 http/2 最相关的部分是在端口 443 上的两个侦听指令之后的 http2 关键字。添加这些关键字后,服务器开始使用 http/2,该站点现在似乎可以在 Safari 15.2 和 WebKit-based iOS 浏览器中正常运行。希望这对某人有帮助!