【问题标题】:Why nginx add_headers doesn't work properly?为什么 nginx add_headers 不能正常工作?
【发布时间】:2022-06-11 04:34:20
【问题描述】:

我使用 Nginx 作为 Web 服务器。 这是我的nginx.conf 文件:

server {

    listen 80;

    root /usr/share/nginx/html;
    index index.html index.htm;

    location ^~ /start/ {
        add_header 'Cross-Origin-Embedder-Policy' 'require-corp';
        add_header 'Cross-Origin-Opener-Policy' 'same-origin';
        try_files $uri $uri/ /index.html;
    }

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

当我在浏览器上打开此链接时,我在响应标头部分的网络选项卡中看不到标头: https://example.com/start/629852d359d2a400034698a2

【问题讨论】:

    标签: nginx http-headers


    【解决方案1】:

    实际上add_header 指令可以正常工作。很可能没有添加标头,因为您的服务器上没有 /usr/share/nginx/html/start/629852d359d2a400034698a2 文件或目录,因此根据最后一个 try_files 指令参数将请求重写为 /index.html,然后由您的 location / { ... } 处理(因为新的 URI 不以 /start/ 前缀开头),并且该位置没有设置任何额外的标头。


    通常,如果那些以/start/ 为前缀的 URI 可能是内部应用程序路由或外部资产链接,则可以使用 map 块来评估所需的标头值来解决:

    map $uri $add_policies {
        ~^/start/  1;
        # default value will be an empty string, unless specified explicitly
    }
    map $add_policies $embedder_policy {
        1  require-corp;
    }
    map $add_policies $opener_policy {
        1  same-origin;
    }
    server {
        ...
        location / {
            add_header Cross-Origin-Embedder-Policy $embedder_policy;
            add_header Cross-Origin-Opener-Policy $origin_policy;
            try_files $uri $uri/ /index.html;
        }
    }
    

    此解决方案基于add_header行为,即如果提供的值为空字符串,则根本不将指定的标头添加到响应中。

    但是,如果您确定应该添加这些标头的 URI 是应用程序路由,而不是指向物理现有文件的链接,那么您还有一个选择:

    server {
        ...
        location ^~ /start/ {
            set $embedder_policy require-corp;
            set $origin_policy same-origin;
            rewrite ^ /index.html last;
        }
        location / {
            add_header Cross-Origin-Embedder-Policy $embedder_policy;
            add_header Cross-Origin-Opener-Policy $origin_policy;
            try_files $uri $uri/ /index.html;
        }
    }
    

    此解决方案的性能应该更高一些,因为它不需要(某种昂贵的)PCRE 库调用来执行正则表达式匹配操作。

    更新

    查看我的答案,我发现最后一个配置可以使用rewrite ... break 而不是rewrite ... last 变得更加简单:

    server {
        ...
        location ^~ /start/ {
            add_header Cross-Origin-Embedder-Policy require-corp;
            add_header Cross-Origin-Opener-Policy same-origin;
            rewrite ^ /index.html break;
        }
        location / {
            try_files $uri $uri/ /index.html;
        }
    }
    

    【讨论】:

    • 感谢伊万的回答!我该如何解决?
    • 抱歉,具体解决什么问题?您没有描述您的环境或正在服务的 Web 应用程序的任何内容,我不知道 /start/ URI 后缀在这里是什么意思,是包含另一个 Web 应用程序或虚拟路由前缀等的目录名称,等等。
    • 对不起,我有一个 SPA。我只想在以start/ 开头的路由中添加这些标题。
    • 那么,所有以/start/ 开头的前缀都应该被视为SPA 路由(使用/index.html 控制器处理),对吧?它不能是任何 SPA 资产,因此我们可以跳过检查“$uri 是否为现有文件/目录”?
    • /start/ 路线已显示在新窗口中,但已通过主 SPA 处理
    猜你喜欢
    • 1970-01-01
    • 2016-07-16
    • 2019-01-04
    • 2020-09-03
    • 2016-10-10
    • 2016-10-24
    • 2017-02-27
    • 2017-07-08
    • 2014-11-23
    相关资源
    最近更新 更多