7 HTTP 头

原文链接: https://tauri.app/security/http-headers/

需要 Tauri 2.1.0 或更高版本。

在配置中定义的头会随响应一起发送给 webview。 这不包括 IPC 消息和错误响应。 更具体地说,通过 crates/tauri/src/protocol/tauri.rs ↗ 中的 get_response 函数发送的每个响应都会包含这些头。

头名称

头名称仅限于:

如何配置头

  • 用一个字符串
  • 用字符串数组
  • 用对象/键值对,其中值必须是字符串
  • 用 null

头的值在实际响应中总会被转换为字符串。根据配置文件的写法,有些头的值需要组合。组合的规则如下:

  • string:作为结果的头值保持不变
  • array:各项用 , 连接,作为结果的头值
  • key-value:各项由 键 + 空格 + 值 组成,各项之间再用 ; 连接,作为结果的头值
  • null:该头会被忽略

示例

src-tauri/tauri.conf.json

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
 //...
  "app":{
    //...
    "security": {
      //...
      "headers": {
        "Cross-Origin-Opener-Policy": "same-origin",
        "Cross-Origin-Embedder-Policy": "require-corp",
        "Timing-Allow-Origin": [
          "https://developer.mozilla.org",
          "https://example.com",
        ],
        "X-Content-Type-Options": null, // 会被忽略
        "Access-Control-Expose-Headers": "Tauri-Custom-Header",
        "Tauri-Custom-Header": {
          "key1": "'value1' 'value2'",
          "key2": "'value3'"
        }
      },
      // 注意 CSP 不是在 headers 下定义的
      "csp": "default-src 'self'; connect-src ipc: http://ipc.localhost",
    }
  }
}

在这个示例中,Cross-Origin-Opener-Policy 和 Cross-Origin-Embedder-Policy 的设置是为了允许使用 SharedArrayBuffer ↗。 Timing-Allow-Origin 允许从所列网站加载的脚本通过 Resource Timing API ↗ 访问详细的网络计时数据。

对 helloworld 示例来说,该配置会产生:

1
2
3
4
5
6
7
access-control-expose-headers: Tauri-Custom-Header
content-security-policy: default-src 'self'; connect-src ipc: http://ipc.localhost; script-src 'self' 'sha256-Wjjrs6qinmnr+tOry8x8PPwI77eGpUFR3EEGZktjJNs='
content-type: text/html
cross-origin-embedder-policy: require-corp
cross-origin-opener-policy: same-origin
tauri-custom-header: key1 'value1' 'value2'; key2 'value3'
timing-allow-origin: https://developer.mozilla.org, https://example.com

框架

有些开发环境需要额外设置,才能模拟生产环境。

JavaScript/TypeScript

对于使用构建工具 Vite 的项目(包括 Qwik、React、Solid、Svelte 和 Vue),把想要的头加入 vite.config.ts。

vite.config.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { defineConfig } from 'vite';

export default defineConfig({
  // ...
  server: {
      // ...
      headers: {
        'Cross-Origin-Opener-Policy': 'same-origin',
        'Cross-Origin-Embedder-Policy': 'require-corp',
        'Timing-Allow-Origin': 'https://developer.mozilla.org, https://example.com',
        'Access-Control-Expose-Headers': 'Tauri-Custom-Header',
        'Tauri-Custom-Header': "key1 'value1' 'value2'; key2 'value3'"
      },
    },
})

有时 vite.config.ts 会集成到框架的配置文件中,但设置方式不变。如果是 Angular,请把它们加入 angular.json。

angular.json

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
  //...
  "projects":{
    //...
    "insert-project-name":{
      //...
      "architect":{
        //...
        "serve":{
          //...
          "options":{
            //...
            "headers":{
              "Cross-Origin-Opener-Policy": "same-origin",
              "Cross-Origin-Embedder-Policy": "require-corp",
              "Timing-Allow-Origin": "https://developer.mozilla.org, https://example.com",
              "Access-Control-Expose-Headers": "Tauri-Custom-Header",
              "Tauri-Custom-Header": "key1 'value1' 'value2'; key2 'value3'"
            }
          }
        }
      }
    }
  }
}

如果是 Nuxt,请把它们加入 nuxt.config.ts。

nuxt.config.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
export default defineNuxtConfig({
  //...
  vite: {
    //...
    server: {
      //...
      headers:{
        'Cross-Origin-Opener-Policy': 'same-origin',
        'Cross-Origin-Embedder-Policy': 'require-corp',
        'Timing-Allow-Origin': 'https://developer.mozilla.org, https://example.com',
        'Access-Control-Expose-Headers': 'Tauri-Custom-Header',
        'Tauri-Custom-Header': "key1 'value1' 'value2'; key2 'value3'"
      }
    },
  },
});

Next.js 不依赖 Vite,所以做法不同。更多信息请见这里 ↗。这些头在 next.config.js 中定义。

next.config.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
module.exports = {
  //...
  async headers() {
    return [
      {
        source: '/*',
        headers: [
          {
            key: 'Cross-Origin-Opener-Policy',
            value: 'same-origin',
          },
          {
            key: 'Cross-Origin-Embedder-Policy',
            value: 'require-corp',
          },
          {
            key: 'Timing-Allow-Origin',
            value: 'https://developer.mozilla.org, https://example.com',
          },
          {
            key: 'Access-Control-Expose-Headers',
            value: 'Tauri-Custom-Header',
          },
          {
            key: 'Tauri-Custom-Header',
            value: "key1 'value1' 'value2'; key2 'value3'",
          },
        ],
      },
    ]
  },
}

Rust

对于 Yew 和 Leptos,请把这些头加入 Trunk.toml。

Trunk.toml

1
2
3
4
5
6
7
8
9
[serve]
#...
headers = { 
  "Cross-Origin-Opener-Policy" = "same-origin",
  "Cross-Origin-Embedder-Policy" = "require-corp",
  "Timing-Allow-Origin" = "https://developer.mozilla.org, https://example.com",
  "Access-Control-Expose-Headers" = "Tauri-Custom-Header",
  "Tauri-Custom-Header" = "key1 'value1' 'value2'; key2 'value3'"
}
最后修改 September 28, 2026: 更新 (7d1d86223)