From 065f06bd35a77ba97a5822a6d1611f0c991f81f7 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 8 Sep 2024 21:58:14 +0400 Subject: [PATCH 01/30] [ru] fix links and typo in `Learn/CSS/CSS_layout/Flexbox` (#23420) * fix links * fix typo --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Leonid Vinogradov --- files/ru/learn/css/css_layout/flexbox/index.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/files/ru/learn/css/css_layout/flexbox/index.md b/files/ru/learn/css/css_layout/flexbox/index.md index f68d766c12ddb6..86cd9de82a8a37 100644 --- a/files/ru/learn/css/css_layout/flexbox/index.md +++ b/files/ru/learn/css/css_layout/flexbox/index.md @@ -7,9 +7,9 @@ slug: Learn/CSS/CSS_layout/Flexbox Это новая технология, которая уже имеет достаточно широкую поддержку браузеров. Flexbox предоставляет инструменты для быстрого создания сложных, гибких макетов, и функции, которые были сложны в традиционных методах CSS. В этой статье объясняются все основы данной технологии. -| Необходимые навыки: | HTML основы (изучите [Введение в HTML](/ru/docs/Learn/HTML/Введение_в_HTML)), знание того, как работает CSS (изучите [Вступление в CSS](/ru/docs/Learn/CSS/Introduction_to_CSS)). | -| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Цель: | Узнать, как использовать систему адаптируемых блоков Flexbox для создания веб-макетов. | +| Необходимые навыки: | HTML основы (изучите [Введение в HTML](/ru/docs/Learn/HTML/Introduction_to_HTML)), знание того, как работает CSS (изучите [Вступление в CSS](/ru/docs/Learn/CSS/First_steps)). | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Цель: | Узнать, как использовать систему адаптируемых блоков Flexbox для создания веб-макетов. | ## Почему Flexbox? @@ -25,7 +25,7 @@ slug: Learn/CSS/CSS_layout/Flexbox ## Разберём простой пример -В этой статье вы проработаете серию упражнений, которые помогут понять, как работает flexbox. Чтобы начать, скачайте на компьютер стартовый файл — [flexbox0.html](https://github.com/mdn/learning-area/blob/master/css/css-layout/flexbox/flexbox0.html) с нашего Github репозитория — загрузите его в современном браузере (Firefox или Chrome), а также в любимом редакторе кода. Также вы можете [посмотреть его вживую](http://mdn.github.io/learning-area/css/css-layout/flexbox/flexbox0.html). +В этой статье вы проработаете серию упражнений, которые помогут понять, как работает flexbox. Чтобы начать, скачайте на компьютер стартовый файл — [flexbox0.html](https://github.com/mdn/learning-area/blob/master/css/css-layout/flexbox/flexbox0.html) с нашего Github репозитория — загрузите его в современном браузере (Firefox или Chrome), а также в любимом редакторе кода. Также вы можете [посмотреть его вживую](https://mdn.github.io/learning-area/css/css-layout/flexbox/flexbox0.html). Вы увидите элемент {{htmlelement("header")}} с заголовком верхнего уровня внутри, и элемент {{htmlelement("section")}} содержащий три элемента {{htmlelement("article")}}. Мы будем использовать их для создания стандартного трёхколоночного макета. @@ -79,7 +79,7 @@ flex-direction: column; ## Перенос строк -Проблема может быть в том, что, если у вас фиксированная ширина или высота макета, ваши flexbox элементы переполнят контейнер и нарушат макет. Посмотрите на этот пример: [flexbox-wrap0.html](https://github.com/mdn/learning-area/blob/master/css/css-layout/flexbox/flexbox-wrap0.html) и [посмотрите его вживую](http://mdn.github.io/learning-area/css/css-layout/flexbox/flexbox-wrap0.html) (сохраните его себе на компьютер, если хотите изучить этот пример): +Проблема может быть в том, что, если у вас фиксированная ширина или высота макета, ваши flexbox элементы переполнят контейнер и нарушат макет. Посмотрите на этот пример: [flexbox-wrap0.html](https://github.com/mdn/learning-area/blob/master/css/css-layout/flexbox/flexbox-wrap0.html) и [посмотрите его вживую](https://mdn.github.io/learning-area/css/css-layout/flexbox/flexbox-wrap0.html) (сохраните его себе на компьютер, если хотите изучить этот пример): ![](flexbox-example3.png) @@ -89,7 +89,7 @@ flex-direction: column; flex-wrap: wrap; ``` -Также добавьте следующее свойство в CSS-правило для {{htmlelement("arcticle")}}: +Также добавьте следующее свойство в CSS-правило для {{htmlelement("article")}}: ```css flex: 200px; @@ -120,7 +120,7 @@ flex-flow: row wrap; ## Гибкое изменение размеров flex элементов -Теперь давайте вернёмся к нашему первому примеру и посмотрим, как мы можем контролировать, в каких пропорциях flex элементы будут занимать место. Включите свою копию файла [flexbox0.html](https://github.com/mdn/learning-area/blob/master/css/css-layout/flexbox/flexbox0.html), или скачайте [flexbox1.html](https://github.com/mdn/learning-area/blob/master/css/css-layout/flexbox/flexbox1.html) ([просмотр](http://mdn.github.io/learning-area/css/css-layout/flexbox/flexbox1.html)). +Теперь давайте вернёмся к нашему первому примеру и посмотрим, как мы можем контролировать, в каких пропорциях flex элементы будут занимать место. Включите свою копию файла [flexbox0.html](https://github.com/mdn/learning-area/blob/master/css/css-layout/flexbox/flexbox0.html), или скачайте [flexbox1.html](https://github.com/mdn/learning-area/blob/master/css/css-layout/flexbox/flexbox1.html) ([просмотр](https://mdn.github.io/learning-area/css/css-layout/flexbox/flexbox1.html)). Прежде всего, добавим следующее правило в конец вашего CSS кода: @@ -172,7 +172,7 @@ article:nth-of-type(3) { ## Горизонтальное и вертикальное выравнивание -Flexbox также имеет функции для выравнивания flex элементов вдоль основной (main) или поперечной (cross) осей. Рассмотрим их на новом примере — [flex-align0.html](https://github.com/mdn/learning-area/blob/master/css/css-layout/flexbox/flex-align0.html) ([просмотр](http://mdn.github.io/learning-area/css/css-layout/flexbox/flex-align0.html)) — который мы превратим в аккуратную, гибкую кнопочную панель инструментов. На данный момент вы видите горизонтальную панель меню, кнопки которой застряли в верхнем левом углу. +Flexbox также имеет функции для выравнивания flex элементов вдоль основной (main) или поперечной (cross) осей. Рассмотрим их на новом примере — [flex-align0.html](https://github.com/mdn/learning-area/blob/master/css/css-layout/flexbox/flex-align0.html) ([просмотр](https://mdn.github.io/learning-area/css/css-layout/flexbox/flex-align0.html)) — который мы превратим в аккуратную, гибкую кнопочную панель инструментов. На данный момент вы видите горизонтальную панель меню, кнопки которой застряли в верхнем левом углу. ![](flexbox-example5.png) @@ -245,7 +245,7 @@ button:last-child { ## Вложенные flex блоки -Можно создать несколько довольно сложных макетов с помощью flexbox. Совершенно нормально сделать flex элемент flex контейнером, чтобы его потомки также были flex блоками. Посмотрите на [complex-flexbox.html](https://github.com/mdn/learning-area/blob/master/css/css-layout/flexbox/complex-flexbox.html) ([см. вживую](http://mdn.github.io/learning-area/css/css-layout/flexbox/complex-flexbox.html)). +Можно создать несколько довольно сложных макетов с помощью flexbox. Совершенно нормально сделать flex элемент flex контейнером, чтобы его потомки также были flex блоками. Посмотрите на [complex-flexbox.html](https://github.com/mdn/learning-area/blob/master/css/css-layout/flexbox/complex-flexbox.html) ([см. вживую](https://mdn.github.io/learning-area/css/css-layout/flexbox/complex-flexbox.html)). ![](flexbox-example7.png) From fed9ad9d0412a8e2e544e67cb3fb41308c6f6de9 Mon Sep 17 00:00:00 2001 From: familyboat <84062528+familyboat@users.noreply.github.com> Date: Mon, 9 Sep 2024 08:55:26 +0800 Subject: [PATCH 02/30] zh-cn: update the translation of the learn/css index page (#23446) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: A1lo --- files/zh-cn/learn/css/index.md | 42 +++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/files/zh-cn/learn/css/index.md b/files/zh-cn/learn/css/index.md index 445c058f77add0..19c8fc5d7f26d7 100644 --- a/files/zh-cn/learn/css/index.md +++ b/files/zh-cn/learn/css/index.md @@ -7,44 +7,48 @@ l10n: {{LearnSidebar}} -层叠样式表——或 {{glossary("CSS")}}——是你在 {{glossary("HTML")}} 之后应该学习的第二门技术。HTML 用于定义内容的结构和语义,CSS 用于设计风格和布局。比如,你可以使用 CSS 来更改内容的字体、颜色、大小、间距,将内容分为多列,或者添加动画及其他的装饰效果。 +层叠样式表——或 {{glossary("CSS")}}——是你在学完 {{glossary("HTML")}} 之后应该学习的第一门技术。HTML 用于为你的内容定义结构和语义,CSS 用于为内容提供样式和对内容进行布局。例如,你可以使用 CSS 更改内容的字体、颜色、大小和间距,将内容分成多列,或添加动画和其它装饰特性。 -## 学习路径 +## 前提 -在尝试学习 CSS 之前,你应该了解 HTML 的基础知识。建议你先学习 [HTML 简介](/zh-CN/docs/Learn/HTML/Introduction_to_HTML)模块。 +在尝试 CSS 之前,你应该学习 HTML 的基础知识。我们建议你先学习 [HTML 简介](/zh-CN/docs/Learn/HTML/Introduction_to_HTML)。 -一旦你掌握了 HTML 的基础知识,我们建议你同时学习更深入的 HTML 和 CSS,在这两个主题之间来回切换学习。这是因为当你应用 CSS 时,HTML 会变得更加有趣,学习起来也更有乐趣,而不了解 HTML 就无法学习 CSS。 +一旦你理解了 HTML 的基础知识,我们就建议你同时更深入地学习 HTML 和 CSS,在这两个专题之间来回切换。这么做是因为在应用了 CSS 后,HTML 会变得更加有趣,学习起来也更有乐趣。并且不了解 HTML 的话,也无法学习 CSS。 -在开始这个主题之前,你还应该熟悉使用计算机和被动地使用网络(即,仅仅浏览和消费内容)。你应该按照[安装基础软件](/zh-CN/docs/Learn/Getting_started_with_the_web/Installing_basic_software)中详细说明的内容设置好一个基本的工作环境,并且理解如何创建和管理文件,这在[处理文件](/zh-CN/docs/Learn/Getting_started_with_the_web/Dealing_with_files)中有详细介绍——这些都是我们从零[开始学网页](/zh-CN/docs/Learn/Getting_started_with_the_web)初学者完整模块的一部分。 +在开始本专题之前,你还应该熟悉如何使用电脑,如何被动地使用 Web(例如,只是浏览和消费内容)。你应该按照[安装基础软件](/zh-CN/docs/Learn/Getting_started_with_the_web/Installing_basic_software)中的详细内容搭建基础工作环境,以及按照[处理文件](/zh-CN/docs/Learn/Getting_started_with_the_web/Dealing_with_files)中的内容理解如何创建和管理文件——两个都是 [Web 入门](/zh-CN/docs/Learn/Getting_started_with_the_web)纯新手模块的一部分。 -如果你对网页开发完全陌生,建议你在继续学习这个主题之前,先完成从零[开始学网页](/zh-CN/docs/Learn/Getting_started_with_the_web)的学习。不过,[CSS 基础](/zh-CN/docs/Learn/Getting_started_with_the_web/CSS_basics)文章中涵盖的大部分内容也在我们的 [CSS 第一步](/zh-CN/docs/Learn/CSS/First_steps)模块中有更详细的讲解。 +在开始本专题之前,还是建议你先学习 [Web 入门](/zh-CN/docs/Learn/Getting_started_with_the_web),尤其当你是 Web 开发的纯新手的话。不过,[CSS 基础](/zh-CN/docs/Learn/Getting_started_with_the_web/CSS_basics)这篇文章中涉及的大部分内容在 [CSS 第一步](/zh-CN/docs/Learn/CSS/First_steps)模块中也有所涉及,而且更详细。 ## 模块 -本主题包含以下模块,建议按顺序阅读这些模块。你应该从第一个模块开始。 +本专题包含以下模块,建议按顺序学习这些模块。你应该从第一个模块开始。 - [CSS 第一步](/zh-CN/docs/Learn/CSS/First_steps) - - : CSS(层叠样式表)用于样式化和布局网页。例如,可以更改内容的字体、颜色、大小和间距,将内容分成多列,或添加动画和其他装饰功能。本模块将为你提供通往精通 CSS 之路的平缓起点,让你了解 CSS 的基本工作原理、语法,以及如何开始使用 CSS 为 HTML 添加样式。 -- [构建 CSS 块](/zh-CN/docs/Learn/CSS/Building_Blocks) - - : 本模块承接 [CSS 第一步](/zh-CN/docs/Learn/CSS/First_steps),进行进一步的学习——既然你已经熟悉了 CSS 的语言和语法,有了一些使用 CSS 的基本经验,是时候再深入一些了。本模块涉及了层叠与继承、可用的所有种类的选择器、单位、尺寸、样式化背景和边框、调试,还有更多。这样做的目的是,在继续深入到更加具体的规则,例如[样式化文本](/zh-CN/docs/Learn/CSS/Styling_text)和 [CSS 布局](/zh-CN/docs/Learn/CSS/CSS_layout)前,为你提供一个编写合格 CSS 的工具包,帮你理解所有必要的理论。 -- [样式化文本](/zh-CN/docs/Learn/CSS/Styling_text) - - : 在覆盖了 CSS 语言的基础知识之后,下一个需要集中学习的 CSS 主题是文本样式化——这是你使用 CSS 最常做的事情之一。这里我们研究文本样式化的基本原理,包括设置字体、粗细、斜体、行距和字母间距、阴影等文本特征。我们最后还会讨论如何将自定义字体应用到页面上,以及如何样式化列表和链接。 + - : CSS(层叠样式表)用于为网页添加样式,对网页进行布局——例如,修改内容的字体、颜色、大小和间距,将内容分成多列,或添加动画和其它装饰特性。在前往掌握 CSS 基础知识(CSS 的运作方式,CSS 语法是什么样子,在 HTML 中如何使用 CSS 添加样式)的道路上,本模块是一个很好的开始。 +- [CSS 构建块](/zh-CN/docs/Learn/CSS/Building_Blocks) + + - : 本模块承接 [CSS 第一步](/zh-CN/docs/Learn/CSS/First_steps)——这时你已经熟悉 CSS 语言及其语法,有了基本的使用经验,是时候再深入一些。在本模块中,你会学习层叠和继承、可用的选择器类型、单位、大小、为背景和边框添加样式、调试,以及其它内容。 + + 本文的目的是,在了解诸如[为文本添加样式](/zh-CN/docs/Learn/CSS/Styling_text)和 [CSS 布局](/zh-CN/docs/Learn/CSS/CSS_layout)等特定领域的知识之前,提供一个能让你编写合格 CSS 的工具集并帮助你理解基本的理论。 + +- [为文本添加样式](/zh-CN/docs/Learn/CSS/Styling_text) + - : 在学完 CSS 语言的基础知识后,下一个集中学习的 CSS 主题是为文本添加样式——用 CSS 做的最多的事之一。本文介绍了为文本添加样式的基础知识,包括:设置字体、加粗、斜体、行间距、字间距、阴影和其它文本特性。在本模块中,还会学习的内容有:在页面中应用自定义字体、为列表和链接添加样式。 - [CSS 布局](/zh-CN/docs/Learn/CSS/CSS_layout) - - : 到目前为止,我们已经学习了 CSS 基础知识、如何设置文本样式、如何设计并操作内容所在的盒子。现在应该考虑如何把你的盒子以合适的位置放置在视口内和其他盒子旁边了。我们已经学习了在深入 CSS 布局之前需要学会的必要知识,下一步我们通过学习设置 display 属性,使用新的布局工具如弹性盒(flexbox)、CSS 网格和定位,以及你仍想知道的一些传统技术,来深入学习 CSS 布局。 + - : 看到这儿,你已经学习过 CSS 基础知识、如何为文本添加样式、如何为放置内容的盒子添加样式并操纵它。现在,是时候学习参照视口或另一个盒子时如何将盒子放置在正确的位置。必要的前置知识已经具备,此时你可以深入 CSS 布局,学习不同的显示设置、现代的布局工具(如弹性盒、CSS 网格)、定位,以及一些你可能仍想了解的传统技术。 ## 解决常见的 CSS 问题 -[使用 CSS 解决常见问题](/zh-CN/docs/Learn/CSS/Howto)解释了怎样使用 CSS 解决创建一个网页时常遇到的问题。 +[使用 CSS 解决常见问题](/zh-CN/docs/Learn/CSS/Howto)提供了用于解释如何使用 CSS 解决创建网页时常遇到的问题的内容的链接。 -从这里开始,你大致就能在 HTML 元素和它们的背景上应用颜色、改变形状尺寸和元素的位置、向元素上添加并定义边框。但是,只要你对 CSS 的基础知识有了扎实的了解,就没有做不到的事情了。学习 CSS 的最大好处之一就是,一旦你了解了 CSS 的基础知识,即使你还不知道如何操作,通常也能很好地了解哪些可以做到,哪些不可以做到! +刚开始,你主要是为 HTML 元素及其背景应用颜色,改变元素的大小、形状和位置,为元素添加和定义边框。但这并不是你唯一能做的,只要你对 CSS 的基础知识有了坚实的理解的话。学习 CSS 最棒的事情之一就是,一旦你了解了基础,即使你还不知道如何做,通常会对能做的和不能做的有一个很好的感知。 -## “CSS 是怪异的” +## “CSS 真奇怪” -CSS 确实有些独特,它的工作方式与大多数编程语言和设计工具有些不同。为什么 CSS 会以这种方式工作呢?在下面的视频中,Miriam Suzanne 提供了一个有用的解释,说明了 CSS 为什么会这样工作,以及为什么它会这样演变: +CSS 与你接触到的大多数编程语言和设计工具的运作方式有点不同。CSS 为什么以这种方式运作?在下面的视频中,对 CSS 为什么这样运作以及 CSS 为什么演变成这样做了很好的解释: {{EmbedYouTube("aHUtMbJw8iA")}} -## 参阅 +## 参见 - [MDN 上的 CSS 文档](/zh-CN/docs/Web/CSS) - - : MDN 上 CSS 文档的主要入口,可以在这里找到 CSS 语言所有特性的详细参考文档。想要了解某个属性可以取的所有值吗?这是一个很好的去处。 + - : MDN 上 CSS 文档的主入口,在这里可以找到 CSS 语言全部特性的详细参考文档。想要了解某个属性可以取的所有值吗?这是一个很好的去处。 From 71cd8ddcb0eb7edeac8f83a6a418676bb129f3fc Mon Sep 17 00:00:00 2001 From: familyboat <84062528+familyboat@users.noreply.github.com> Date: Mon, 9 Sep 2024 11:50:46 +0800 Subject: [PATCH 03/30] zh-cn: update the translation of the home page of learn (#23483) --- files/zh-cn/learn/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/zh-cn/learn/index.md b/files/zh-cn/learn/index.md index 4a034f032cf040..64a62faebde32a 100644 --- a/files/zh-cn/learn/index.md +++ b/files/zh-cn/learn/index.md @@ -16,7 +16,7 @@ l10n: 你要是还不确定是否要深入地学习 Web 开发,仅想从体验环节开始,我们会建议你从 [Web 入门](/zh-CN/docs/Learn/Getting_started_with_the_web)指南开始学习。除此之外,你应该从下面的专题开始学习。 - HTML 和 CSS - - : HTML 为 Web 内容提供结构,而 CSS 为 Web 内容添加样式并对 Web 内容进行布局。在[介绍 HTML](/zh-CN/docs/Learn/HTML/Introduction_to_HTML) 和 [CSS 第一步](/zh-CN/docs/Learn/CSS/First_steps)中学习基本的入门知识。 + - : HTML 为 Web 内容提供结构,而 CSS 为 Web 内容添加样式并对 Web 内容进行布局。在 [HTML 简介](/zh-CN/docs/Learn/HTML/Introduction_to_HTML)和 [CSS 第一步](/zh-CN/docs/Learn/CSS/First_steps)中学习基本的入门知识。 - JavaScript - : JavaScript 为网站提供交互功能。从 [JavaScript 第一步](/zh-CN/docs/Learn/JavaScript/First_steps)开始学习。 - 框架和工具 @@ -29,7 +29,7 @@ l10n: > > #### 想成为一名前端 Web 开发者吗? > -> 你要是想成为一名前端 Web 开发者,但不确定该从哪开始学习,我们会建议使用 [MDN 合作课程](/en-US/curriculum/)作为你的学习计划。它提供一个结构化的学习路径,包含:成为一名成功的前端开发者所需的基本技巧和练习,以及推荐学习资源。 +> 你要是想成为一名前端 Web 开发者,但不确定该从哪开始学习,我们会建议使用 [MDN 课程](/en-US/curriculum/)作为你的学习计划。它提供一个结构化的学习路径,包含:成为一名成功的前端开发者所需的基本技巧和练习,以及推荐学习资源。 > > [**现在开始**](/en-US/curriculum/) From e7b8882784dcf1d8234ffe6ff4141a9d377da284 Mon Sep 17 00:00:00 2001 From: Tianyi Tao Date: Mon, 9 Sep 2024 13:28:10 +0800 Subject: [PATCH 04/30] [zh-cn]: update the translation of `global_objects/nan` (#23464) Co-authored-by: A1lo --- .../reference/global_objects/nan/index.md | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/files/zh-cn/web/javascript/reference/global_objects/nan/index.md b/files/zh-cn/web/javascript/reference/global_objects/nan/index.md index c10489297bdbff..cb6b5128933288 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/nan/index.md +++ b/files/zh-cn/web/javascript/reference/global_objects/nan/index.md @@ -1,21 +1,27 @@ --- title: NaN slug: Web/JavaScript/Reference/Global_Objects/NaN +l10n: + sourceCommit: 915c9519f3cca1c616c2f554d5ad9e1483bbb170 --- {{jsSidebar("Objects")}} 全局属性 **`NaN`** 是一个表示非数字的值。 -{{js_property_attributes(0, 0, 0)}} - {{EmbedInteractiveExample("pages/js/globalprops-nan.html")}} +## 值 + +其与 {{jsxref("Number.NaN")}} 的值相同。 + +{{js_property_attributes(0, 0, 0)}} + ## 描述 -`NaN`是*全局对象*的一个属性。换句话说,它是全局作用域中的一个变量。 +`NaN` 是*全局对象*的一个属性。换句话说,它是全局作用域中的一个变量。 -`NaN` 的初始值不是数字——与 {{jsxref("Number.NaN")}} 的值相同。在现代浏览器中,`NaN` 是一个不可配置、不可写的属性。即使不是这样,也要避免重写它。在程序中很少使用 `NaN`。 +在现代浏览器中,`NaN` 是一个不可配置、不可写的属性。即使不是这样,也要避免重写它。 有五种不同类型的操作返回 `NaN`: @@ -27,8 +33,8 @@ slug: Web/JavaScript/Reference/Global_Objects/NaN `NaN` 及其行为不是 JavaScript 发明的。它在浮点运算中的语义(包括 `NaN !== NaN`)是由 [IEEE 754](https://zh.wikipedia.org/wiki/雙精度浮點數) 指定的。`NaN` 的行为包括: -- 如果 `NaN` 涉及数学运算(但不涉及[位运算](/zh-CN/docs/Web/JavaScript/Reference/Operators#位移运算符)),结果通常也是 `NaN`。(参见下面的[反例](#默默逃离_nan)。) -- 当 `NaN` 是任何关系比较(`>`, `<`, `>=`, `<=`)的操作数之一时,结果总是 `false`。 +- 如果 `NaN` 涉及数学运算(但不涉及[位运算](/zh-CN/docs/Web/JavaScript/Reference/Operators#位移运算符)),结果通常也是 `NaN`。(参见下面的[反例](#静默逃逸的_nan_值)。) +- 当 `NaN` 是任何关系比较(`>`、`<`、`>=`、`<=`)的操作数之一时,结果总是 `false`。 - `NaN` 不等于(通过 [`==`](/zh-CN/docs/Web/JavaScript/Reference/Operators/Equality)、[`!=`](/zh-CN/docs/Web/JavaScript/Reference/Operators/Inequality)、[`===`](/zh-CN/docs/Web/JavaScript/Reference/Operators/Strict_equality) 和 [`!==`](/zh-CN/docs/Web/JavaScript/Reference/Operators/Strict_inequality))任何其他值——包括与另一个 `NaN` 值。 `NaN` 也是 JavaScript 中的[假](/zh-CN/docs/Glossary/Falsy)值之一。 @@ -75,7 +81,7 @@ const arr = [2, 4, NaN, 12]; arr.indexOf(NaN); // -1 arr.includes(NaN); // true -// Methods accepting a properly defined predicate can always find NaN +// 接受正确定义的断言的方法总是能够找到 NaN arr.findIndex((n) => Number.isNaN(n)); // 2 ``` @@ -83,23 +89,33 @@ arr.findIndex((n) => Number.isNaN(n)); // 2 ### 明显不同的 NaN 值 -这是 `NaN` 与自身不平等的动机。可以用不同的二进制表示生成两个都是 `NaN` 的浮点数,因为在 [IEEE 754 编码](https://zh.wikipedia.org/wiki/NaN#浮点数)中,任何指数为 `0x7ff` 且尾数非零的浮点数都是 `NaN`。在 JavaScript 中,你可以使用[类型化数组](/zh-CN/docs/Web/JavaScript/Typed_arrays)来进行位操作。 +可以用不同的二进制表示生成两个都是 `NaN` 的浮点数,这是因为在 [IEEE 754 编码](https://zh.wikipedia.org/wiki/NaN#浮点数)中,任何指数为 `0x7ff` 且尾数非零的浮点数都是 `NaN`。在 JavaScript 中,你可以使用[类型化数组](/zh-CN/docs/Web/JavaScript/Typed_arrays)来进行位操作。 ```js const f2b = (x) => new Uint8Array(new Float64Array([x]).buffer); const b2f = (x) => new Float64Array(x.buffer)[0]; -// Get a byte representation of NaN +// 获取 NaN 的字节表示 const n = f2b(NaN); -// Change the first bit, which is the sign bit and doesn't matter for NaN -n[0] = 1; +const m = f2b(NaN); +// 更改符号位,对于 NaN 而言,这个比特位不重要。 +n[7] += 2 ** 7; +// n[0] += 2**7; 对于大端处理器 const nan2 = b2f(n); console.log(nan2); // NaN console.log(Object.is(nan2, NaN)); // true console.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127] -console.log(f2b(nan2)); // Uint8Array(8) [1, 0, 0, 0, 0, 0, 248, 127] +console.log(f2b(nan2)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 255] +// 更改第一个比特位,即符号位,对于 NaN 而言,这个比特位不重要。 +m[0] = 1; +// m[7] = 1; 对于大端处理器 +const nan3 = b2f(m); +console.log(nan3); // NaN +console.log(Object.is(nan3, NaN)); // true +console.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127] +console.log(f2b(nan3)); // Uint8Array(8) [1, 0, 0, 0, 0, 0, 248, 127] ``` -### 默默逃离 NaN +### 静默逃逸的 NaN 值 `NaN` 通过数学运算进行传播,因此通常在计算结束时测试 `NaN` 一次就足以检测错误条件。`NaN` 被静默转义的唯一情况是使用指数为 `0` [求幂](/zh-CN/docs/Web/JavaScript/Reference/Operators/Exponentiation)时,它立即返回 `1` 而不测试基数的值。 From a75bf486fd88a3ac5be87e173e4d1dbf7c0712ad Mon Sep 17 00:00:00 2001 From: Hoarfroster Date: Mon, 9 Sep 2024 14:26:58 +0800 Subject: [PATCH 05/30] zh-CN: glossary/color_space (#20022) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: A1lo Co-authored-by: 720 <71604450+T34-active@users.noreply.github.com> Co-authored-by: Jason Ren <40999116+jasonren0403@users.noreply.github.com> --- files/zh-cn/glossary/color_space/index.md | 95 +++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 files/zh-cn/glossary/color_space/index.md diff --git a/files/zh-cn/glossary/color_space/index.md b/files/zh-cn/glossary/color_space/index.md new file mode 100644 index 00000000000000..7780fb8c3d9022 --- /dev/null +++ b/files/zh-cn/glossary/color_space/index.md @@ -0,0 +1,95 @@ +--- +title: 色彩空间 +slug: Glossary/Color_space +l10n: + sourceCommit: 530c1f54e63834411aa38789b1ac82e3831c4dfa +--- + +{{GlossarySidebar}} + +**色彩空间**是对色彩的命名组织方式,用于基于坐标的色彩排列的基本色彩模型。色彩模型定义了色彩的组成部分(例如 [`hwb()`](/zh-CN/docs/Web/CSS/color_value/hwb) 色彩的 `h`、`w` 和 `b` 通道)与色彩空间之间的关系。多数色彩空间是表示色彩的三维或四维网格,其中各维度(轴)对应色彩空间中的一个通道。一个色彩可以在保持看起来仍然一样的情况下在多个色彩空间中表达,或者从一个色彩空间转换到另一个色彩空间。 + +色彩空间对特定范围的色彩进行分类和定义。每个色彩空间由数学模型和相关的规则集定义。每个色彩空间都有一个定义好的{{glossary("gamut", "色域")}}(它指的是它能表示的特定范围的色彩)。这些规则使得跨不同设备和软件的色彩表现一致且可重现。 + +_sRGB_ 色彩空间(标准红绿蓝)是为 Web 创建的,但我们不再局限于这个色彩空间。[CSS 色彩模块第 4 版](https://drafts.csswg.org/css-color-4)指定了几种预定义的色彩空间,而 [CSS 色彩模块第 5 版](https://drafts.csswg.org/css-color-5/)则进一步规定了用于定义自定义色彩空间的特性。 + +## 具名色彩空间 + +预定义的 [RGB 色彩空间](#rgb_色彩空间)包括 `srgb`、`srgb-linear`、`display-p3`、`a98-rgb`、`prophoto-rgb` 和 `rec2020`。预定义的 [CIELAB 色彩空间](#cielab_色彩空间)包括 `lab-d50` 和 `lab-d65`。预定义的 [XYZ 色彩空间](#xyz_色彩空间)包括 `xyz-d50` 和 `xyz-d65`(以及作为其别名的 `xyz`)。 + +色彩空间可以是[矩形或极坐标的](https://ericportis.com/posts/2024/okay-color-spaces/)。矩形色彩空间包括 `srgb`、`srgb-linear`、`display-p3`、`a98-rgb`、`prophoto-rgb`、`rec2020`、`lab`、`oklab`、`xyz-d50` 和 `xyz-d65`(或 `xyz`)。极坐标色彩空间包括 `hsl`、`hwb`、`lch` 和 `oklch`。 + +### RGB 色彩空间 + +RGB 是一种色彩模型,将色彩表示为三个基本成分(红色、绿色和蓝色色彩通道)的混合,产生各种色调。sRGB(标准 RGB)是 {{Glossary("RGB")}} 色彩的底层色彩空间。sRGB 旨在编纂个人电脑及{{glossary("world wide web", "万维网")}}成像系统的显示规范。目前,sRGB 通常是那些没有标记或没有嵌入色彩配置文件的默认色彩空间。 + +RGB 色彩空间有几种,如可以表示比 _sRGB_ 色彩空间更广泛的{{glossary("gamut", "色域")}}的 _Adobe RGB_ 色彩空间。_sRGB_ 和 _Adobe RGB_(`a98-rgb`)中的坐标是不同的。有很多种方式来描述色彩的 RGB 成分:在 {{Glossary("CSS")}} 中,色彩可以表示为十六进制表示法的单个 24 位整数(如淡蓝色 `#add8e6`),或者在 [`rgb()`](/zh-CN/docs/Web/CSS/color_value/rgb) 函数表示法中表示为 0 到 255 之间的三个独立数字(如,`rgb(46 139.5 87)`)。 + +在 sRGB 色彩空间中,CSS `` 值包括{{cssxref("hex-color", "十六进制色彩")}}、{{cssxref("named-color", "具名色彩")}}、{{cssxref("color_value/rgb", "rgb()")}}、{{cssxref("color_value/hsl", "hsl()")}}(色调、饱和度、亮度)和{{cssxref("color_value/hwb", "hwb()")}}(色调、白度、黑度)。[`color`](/zh-CN/docs/Web/CSS/color_value/color) 函数还支持 `srgb`、`srgb-linear`、`a98-rgb` 和 `prophoto-rgb` 色彩空间。 + +HSV(色调、饱和度和值)色彩空间及其同义词 HSB(色调、饱和度和亮度)在 CSS 中都用 [`hwb()`](/zh-CN/docs/Web/CSS/color_value/hwb) 表示。命名色彩只是与特定十六进制值相对应的关键字。将这些不同的色彩表示法转换为 `sRGB` 的数学方法是直观的。请注意,{{cssxref("<color>", "currentcolor", "#currentcolor_关键字")}} 可以是任何色彩,而不仅限于 `sRGB` 色彩空间。 + +`rgb` 色彩函数不是可以用于表示 _sRGB_ 色彩空间的唯一色彩函数。圆柱坐标系,如 [`HSL`](/zh-CN/docs/Web/CSS/color_value/hsl)(_色调—饱和度—亮度_)或 [`HWB`](/zh-CN/docs/Web/CSS/color_value/hwb)(_色调—白度—黑度_)色彩模型也用于在 Web 上表示 sRGB 色彩。 + +- `sRGB` 色彩空间 + - : sRGB 色彩空间(“标准 RGB”),是标准的 RGB(红、绿、蓝)色彩空间,用于显示器、打印机和 Web 中。它是使用最广泛的色彩空间,受到大多数操作系统、软件程序、显示器和打印机的支持。sRGB 以 `r`、`g` 和 `b` 为基础,色域范围为 `0` 至 `1`。它的白点为 D65。 +- `srgb-linear` 色彩空间 + - : 预定义的线性光 sRGB 色彩空间 `srgb-linear` 与 `srgb`相同,只是传输函数是没有伽玛编码的线性光。`srgb-linear` 色彩空间接受三个 `r`、`g` 和 `b` 值作为数值参数,色域范围为 `0` 至 `1`。它的白点为 D65。 +- `display-p3` 色彩空间 + - : **Display P3** 色彩空间由苹果公司定义,结合了 DCI-P3 色域、D65 白点和 sRGB 伽马曲线。它是一种典型的宽色域空间,适用于当前的宽色域显示器,能呈现出比 sRGB 色域更鲜艳的绿色和红色。`display-p3` 基于 `r`、`g` 和 `b`,伽玛值范围为 `0` 至 `1`。它的白点为 D65。 +- `a98-rgb` 色彩空间 + - : `a98-rgb` 是 Adobe® 1998 RGB 色彩空间,旨在将所有 CMYK 颜色表示为 RGB。它可实现 [CIELab 色彩空间](#cielab_色彩空间)指定的约 50% 的可见色彩,比其他 RGB 色彩空间包含更多的青绿色调。伽玛内的 `r`、`g` 和 `b` 值范围从 `0` 到 `1`。它的传输曲线是一个伽马函数,不完全地接近于 1/2.2。它的白点为 D65。 +- `prophoto-rgb` + - : `prophotoo-rgb` 色彩空间由柯达公司开发,可以表示自然界中可能出现的所有颜色和大约 90% 的 [CIElab 颜色](#cielab_色彩空间)。色域范围的 `r`、`g` 和 `b` 值范围从 `0` 至 `1`。转移曲线是一个伽马函数,值为 1/1.8,其中在黑色附近有一小段线性。它的白点为 D50,与 CIELab 使用的白点相同。 +- `rec2020` + - : `rec2020` 是超高清 4k 和 8k 电视的广播行业标准。超宽色域空间能够呈现现实世界中几乎所有可见的颜色,超出了目前大多数显示器的能力。随着显示器的不断改进,预计覆盖范围会逐渐扩大。色域内的 `r`、`g` 和 `b` 值从 `0` 至 `1`。它的白点为 D65。 + +> [!NOTE] +> CSS 规范中没有的其他圆柱形 RGB 空间,如 `HSI`(色调、饱和度和强度)、`Okhsv`、`Okhsl`、`HSLuv`、`HPLuv` 和 `Cubehelix`。 + +### CIELAB 色彩空间 + +CIELAB(或 CIELab)色彩空间,也称为 L\*a\*b*(简称 Lab*),表示人类可以看到的所有色彩范围。这个色彩空间是由国际照明委员会(CIE)定义的。它将色彩表示为三个值:L\* 表示感知亮度,a\* 和 b\* 表示人类视觉的四种独特色彩:红、绿、蓝和黄。 + +Lab 是一个矩形坐标系统,有一个中央的亮度 `L` 轴。`a` 轴上的正值是紫红色,而负值是其补色绿色。`b` 轴上的正值是黄色,负值是蓝色/紫罗兰色。不饱和的色彩具有小的 `a` 和 `b` 值,而绝对值更大的更饱和。 + +CIELAB 色彩函数包括 {{CSSXref("color_value/lab", "lab()")}}(亮度、a 轴、b 轴)和 {{CSSXref("color_value/lch", "lch()")}}(亮度、色度、色调),以及 {{CSSXref("color_value/oklab", "oklab()")}} 和 {{CSSXref("color_value/oklch", "oklch()")}}。它们的亮度值是相同的,但是 `lch()` 和 `oklch` 是一个 `C`(色度)和 `H`(色调)使用极坐标而不是轴的极坐标柱面坐标系统。 + +> [!NOTE] +> 函数 `lch()` 和 `oklch` 中的色调和亮度与 {{cssxref("color_value/hsl", "hsl()")}} 或其他 sRGB 色彩空间中同名值不同。 + +CIELab 色彩空间包括 Lab、Lch、Oklab 和 Oklch,是设备无关的色彩空间。 + +- `lab-d50` 色彩空间 + + - : 将色彩表示为 `L` 在 `0` 到 `100` 范围内,并且 `a` 和 `b` 范围在 `-125` 到 `125` 之间的色彩空间。`a` 和 `b` 轴不受这些范围值的限制,这些值是在与 `Display P3` 色彩空间相关的百分比输入和输出中使用的参考点。它的白点是 D50。 + +- `lab-d65` 色彩空间 + + - : 除使用 D65 作为白点外,与 `lab-d50` 相同。 + +- `oklab` 色彩空间 + + - : 类似于 `lab-d65`,但 `L` 的范围是 `0` 到 `1`,`a` 和 `b` 的范围是 `-0.4` 到 `0.4`。 + +### XYZ 色彩空间 + +尽管红、绿和蓝的组合在屏幕上表示色彩效果很好,但 sRGB 并不直接对应于人类感知的色彩。CIEXYZ(或 XYZ)色彩空间是由国际照明委员会(CIE)在 1931 年定义的。它是电磁可见光谱中波长分布与人类视觉中感知色彩之间的第一个定义的定量联系。 + +视力正常的人有三种对不同波长的光谱具有峰值敏感度的感光锥细胞。CIE X、Y 和 Z 参数对应于三种视锥细胞的刺激水平,原则上可以描述每一种可见光颜色。`Y` 通道代表一种颜色的亮度。`Z` 通道反映颜色中蓝色的含量(但与 RGB 中的 B 不同)。`X` 轴与 XYZ 色彩三维坐标系的 Y 轴和 Z 轴正交。 + +- `xyz` 和 `xyz-d65` 色彩空间 + + - : `xyz` 标识符是 `xyz-d65` 色彩空间的同义词。由于色彩空间不限于此范围,因而轴不限于 `0` 到 `1` 的范围;这些值只在定义输入输出的百分比时使用作为参考点。它的白点是 D65。 + +- `xyz-d50` 色彩空间 + - : 除使用 `d50` 作为白点外,与 `xyz-d65` 相同。 + +## 参见 + +- {{cssxref("@media/color-gamut", "color-gamut")}} `@media` 特性 +- [CSS 数据类型:``](/zh-CN/docs/Web/CSS/color_value) +- [sRGB 色彩空间](https://webstore.iec.ch/en/publication/6168) +- 维基百科上的 [CIELAB 色彩空间](https://zh.wikipedia.org/wiki/CIELAB色彩空间) +- 维基百科上的 [CIE 1931 色彩空间](https://zh.wikipedia.org/wiki/CIE_1931色彩空间) +- [Oklab](https://bottosson.github.io/posts/oklab/) 色彩空间 From 3d0baa0907b59b12d532b9548f8d69abb410d07e Mon Sep 17 00:00:00 2001 From: Hoarfroster Date: Mon, 9 Sep 2024 14:33:44 +0800 Subject: [PATCH 06/30] zh-CN: create Glossary/Canonical_order (#23351) Co-authored-by: Jason Ren <40999116+jasonren0403@users.noreply.github.com> --- files/zh-cn/glossary/canonical_order/index.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 files/zh-cn/glossary/canonical_order/index.md diff --git a/files/zh-cn/glossary/canonical_order/index.md b/files/zh-cn/glossary/canonical_order/index.md new file mode 100644 index 00000000000000..3a62c23616024b --- /dev/null +++ b/files/zh-cn/glossary/canonical_order/index.md @@ -0,0 +1,28 @@ +--- +title: 规范顺序 +slug: Glossary/Canonical_order +l10n: + sourceCommit: 7a551aaa034fbada3eb99e6fc924a0313b78307f +--- + +{{GlossarySidebar}} + +CSS **规范顺序**是指需要指定(或{{Glossary("parse", "解析")}})或作为 CSS 属性值的一部分进行{{Glossary("serialization", "序列化")}}的单独值的顺序。它由属性的正式{{Glossary("syntax", "语法")}}定义,通常指的是应该在单个简写值的一部分中指定全称值的顺序。 + +例如,{{cssxref("background")}} 简写属性值由几个 `background-*` 全称属性组成。这些全称值的规范顺序定义如下: + +1. {{cssxref("background-image")}} +2. {{cssxref("background-position")}} +3. {{cssxref("background-size")}} +4. {{cssxref("background-repeat")}} +5. {{cssxref("background-attachment")}} +6. {{cssxref("background-origin")}} +7. {{cssxref("background-clip")}} +8. {{cssxref("background-color")}} + +另外,它的语法规定如果给出了 {{cssxref("background-size")}} 的值,则这个值**必须**在 {{cssxref("background-position")}} 的值**之后**指定,并用斜杠分隔。其他值则可以以任何顺序出现。 + +## 参见 + +- [CSS 值定义语法](/zh-CN/docs/Web/CSS/Value_definition_syntax) +- StackOverflow 上的[“规范顺序”对 CSS 属性的意义有什么?](https://stackoverflow.com/questions/28963536/what-does-canonical-order-mean-with-respect-to-css-properties)给出了进一步有意义的讨论。 From 32b5677d2dffdffdd9f37661ffd7139058e0b70b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E7=94=B1=E7=9A=84=E4=B8=96=E7=95=8C=E4=BA=BA?= <144885467+Pleasurecruise@users.noreply.github.com> Date: Mon, 9 Sep 2024 15:52:50 +0800 Subject: [PATCH 07/30] [zh-cn] create the translation of "Attribution Reporting API" (#23368) Co-authored-by: Allo --- .../generating_reports/index.md | 308 ++++++++++++++++++ .../api/attribution_reporting_api/index.md | 117 +++++++ .../registering_sources/index.md | 287 ++++++++++++++++ .../registering_triggers/index.md | 231 +++++++++++++ 4 files changed, 943 insertions(+) create mode 100644 files/zh-cn/web/api/attribution_reporting_api/generating_reports/index.md create mode 100644 files/zh-cn/web/api/attribution_reporting_api/index.md create mode 100644 files/zh-cn/web/api/attribution_reporting_api/registering_sources/index.md create mode 100644 files/zh-cn/web/api/attribution_reporting_api/registering_triggers/index.md diff --git a/files/zh-cn/web/api/attribution_reporting_api/generating_reports/index.md b/files/zh-cn/web/api/attribution_reporting_api/generating_reports/index.md new file mode 100644 index 00000000000000..1586a30982b5aa --- /dev/null +++ b/files/zh-cn/web/api/attribution_reporting_api/generating_reports/index.md @@ -0,0 +1,308 @@ +--- +title: 生成归因报告 +slug: Web/API/Attribution_Reporting_API/Generating_reports +l10n: + sourceCommit: f430d277573ba0b06b1ac33ae8017fd90f170bef +--- + +{{SeeCompatTable}}{{DefaultAPISidebar("Attribution Reporting API")}} + +本文介绍了[归因报告 API](/zh-CN/docs/Web/API/Attribution_Reporting_API) 如何生成报告——包括归因报告和调试报告——以及如何控制生成的报告。内容包括处理噪声、报告优先级、过滤报告和生成调试报告。 + +## 基本流程 + +当触发器和来源匹配时,浏览器会生成报告,并通过无凭证的 [`POST`](/zh-CN/docs/Web/HTTP/Methods/POST) 请求将报告发送到报告来源的特定端点: + +- 对于事件级报告,端点为 `/.well-known/attribution-reporting/report-event-attribution`。 +- 对于汇总报告,端点为 `/.well-known/attribution-reporting/report-aggregate-attribution`。 + +`` 与注册的来源(source)和触发器同源(same-origin)。 + +报告数据包含在一个 JSON 结构中。 + +## 事件级报告 + +事件级报告会在其包含的**报告窗口**结束时生成并计划发送。报告窗口的长度由来源的 {{httpheader("Attribution-Reporting-Register-Source")}} 标头中的 [`"event_report_window"`](/zh-CN/docs/Web/HTTP/Headers/Attribution-Reporting-Register-Source#event_report_window) 或 [`"event_report_windows"`](/zh-CN/docs/Web/HTTP/Headers/Attribution-Reporting-Register-Source#event_report_windows) 字段决定。 + +如果未指定这些字段,报告窗口将回退到以下默认值: + +- 对于[基于事件的来源](/zh-CN/docs/Web/API/Attribution_Reporting_API/Registering_sources#基于事件的归因来源),默认报告窗口在来源的 `"expiry"` 到期时结束,该值在 `Attribution-Reporting-Register-Source` 的 [`"expiry"`](/zh-CN/docs/Web/HTTP/Headers/Attribution-Reporting-Register-Source#expiry) 字段中设置。如果未显式设置,则默认为注册后 30 天。 +- 对于[基于导航的来源](/zh-CN/docs/Web/API/Attribution_Reporting_API/Registering_sources#基于导航的归因来源),默认报告窗口分别为 2 天、7 天和来源的 `"expiry"`。 + +有关详细信息,请参阅[自定义报告窗口](https://developers.google.com/privacy-sandbox/private-advertising/attribution-reporting/custom-report-windows)。 + +一旦事件级报告到达相应的端点,数据如何处理、存储和显示完全取决于开发者。一个典型的事件级报告可能如下所示: + +```json +{ + "attribution_destination": "https://advertiser.example", + "source_event_id": "412444888111012", + "trigger_data": "4", + "report_id": "123e4567-e89b-12d3-a456-426614174000", + "source_type": "navigation", + "randomized_trigger_rate": 0.34, + "scheduled_report_time": "1692255696", + "source_debug_key": 647775351539539, + "trigger_debug_key": 647776891539539 +} +``` + +属性如下: + +- `"attribution_destination"` + - : 一个字符串,或者是一个包含 2-3 个字符串的数组,取决于来源是否注册了多个目标。这些字符串代表在来源注册时通过关联的 {{httpheader("Attribution-Reporting-Register-Source")}} 响应标头中设置的归因 [`"destination"`](/zh-CN/docs/Web/HTTP/Headers/Attribution-Reporting-Register-Source#destination) 站点。 +- `"source_event_id"` + - : 一个表示归因来源 ID 的字符串。这等同于在来源注册时通过关联的 {{httpheader("Attribution-Reporting-Register-Source")}} 响应标头中设置的 [`"source_event_id"`](/zh-CN/docs/Web/HTTP/Headers/Attribution-Reporting-Register-Source#source_event_id)。 +- `"trigger_data"` + - : 一个表示归因触发器来源数据的字符串,在触发器注册时设置(通过关联的 {{httpheader("Attribution-Reporting-Register-Trigger")}} 响应标头设置的 [`"trigger_data"`](/zh-CN/docs/Web/HTTP/Headers/Attribution-Reporting-Register-Trigger#trigger_data))。 +- `"report_id"` + - : 一个表示此报告的[通用唯一标识符(UUID)](/zh-CN/docs/Glossary/UUID)的字符串,可用于防止重复计算。 +- `"source_type"` + - : 一个字符串,值为 `"navigation"` 或 `"event"`,分别表示相关的归因来源是[基于导航的](/zh-CN/docs/Web/API/Attribution_Reporting_API/Registering_sources#基于导航的归因来源),还是[基于事件的](/zh-CN/docs/Web/API/Attribution_Reporting_API/Registering_sources#基于事件的归因来源)。 +- `"randomized_trigger_rate"` + - : 一个介于 0 和 1 之间的随机数,表示此特定来源配置应用[噪声](#为报告添加噪声)的频率。 +- `"scheduled_report_time"` + - : 一个字符串,表示从 Unix 纪元开始到浏览器最初计划发送报告的秒数(以避免因设备离线导致报告延迟而产生的不准确性)。 +- `"source_debug_key"` {{optional_inline}} + - : 一个 64 位无符号整数,表示归因来源的调试密钥。此值与关联的 {{httpheader("Attribution-Reporting-Register-Source")}} 标头中的 [`"debug_key"`](/zh-CN/docs/Web/HTTP/Headers/Attribution-Reporting-Register-Source#debug_key) 字段中设置的值相同。有关更多信息,请参阅[调试报告](#调试报告)。 +- `"trigger_debug_key"` {{optional_inline}} + - : 一个 64 位无符号整数,表示归因触发器的调试密钥。此值与关联的 {{httpheader("Attribution-Reporting-Register-Trigger")}} 标头中的 `"debug_key"` 字段中设置的值相同。有关更多信息,请参阅[调试报告](#调试报告)。 + +## 汇总报告 + +汇总报告是从收到的多个可汇总报告创建的,并随后[批处理](https://developers.google.com/privacy-sandbox/private-advertising/attribution-reporting/summary-reports-intro#batching)以准备由[汇总服务](https://developers.google.com/privacy-sandbox/private-advertising/aggregation-service)处理。此后,数据如何处理、存储和显示完全取决于开发者。 + +默认情况下,可汇总报告是在触发器交互后生成并计划发送的,带有随机延迟以帮助模糊时序并提高隐私性。对于给定的已注册归因来源,从注册到来源过期期间会记录归因来源事件——这称为**报告窗口**。 + +到期时间由关联的 {{httpheader("Attribution-Reporting-Register-Source")}} 标头中的 `expiry` 值定义,如果未明确设置,则默认为注册后 30 天。请注意,可以通过在 `Attribution-Reporting-Register-Source` 标头中设置 `aggregatable_report_window` 值来进一步修改报告窗口的长度。有关详细信息,请参阅[自定义报告窗口](https://developers.google.com/privacy-sandbox/private-advertising/attribution-reporting/custom-report-windows)。 + +> [!NOTE] +> 为了进一步保护用户隐私,每个归因来源相关的汇总报告值具有有限的总值——这称为**贡献预算**。此值可能因 API 的不同实现而有所不同;在 Chrome 中为 65,536。任何会生成报告从而导致的总值超出此限制的转化将不被记录。请确保跟踪预算并在你尝试测量的不同指标之间共享它。 + +典型的可汇总报告可能如下所示: + +```json +{ + "shared_info": "{\"api\":\"attribution-reporting\",\"attribution_destination\":\"https://advertiser.example\",\"report_id\":\"123e4567-e89b-12d3-a456-426614174000\",\"reporting_origin\":\"https://reporter.example\",\"scheduled_report_time\":\"1692255696\",\"source_registration_time\":\"1692230400\",\"version\":\"3\"}", + "aggregation_service_payloads": [ + { + "payload": "[base64 编码的 HPKE 加密数据,仅供汇总服务读取]", + "key_id": "[标识用于加密有效负载的公钥的字符串]", + "debug_cleartext_payload": "[base64 编码的未加密有效负载]" + } + ], + "aggregation_coordinator_origin": "https://publickeyservice.aws.privacysandboxservices.com", + "source_debug_key": 647775351539539, + "trigger_debug_key": 647776891539539 +} +``` + +属性如下: + +- `"shared_info"` + - : 这是一个序列化的 JSON 对象,提供汇总服务使用的信息。这些数据使用 [AEAD](https://zh.wikipedia.org/wiki/认证加密) 进行加密,以防篡改。序列化字符串中包含以下属性: + - `"api"` + - : 表示触发报告生成的 API 的枚举值。目前,这个值将始终等于 `"attribution-reporting"`,但将来可能会扩展以支持其他 API。 + - `"attribution_destination"` + - : 一个表示归因 [`"destination"`](/zh-CN/docs/Web/HTTP/Headers/Attribution-Reporting-Register-Source#destination) URL 的字符串,该 URL 在来源注册时通过相关的 {{httpheader("Attribution-Reporting-Register-Source")}} 响应标头设置。 + - `"report_id"` + - : 一个表示此报告的[全局唯一标识符(UUID)](/zh-CN/docs/Glossary/UUID)的字符串,可用于防止重复计数。 + - `"reporting_origin"` + - : 触发报告生成的来源。 + - `"scheduled_report_time"` + - : 一个字符串,表示从 Unix 纪元到浏览器最初计划发送报告的时间,以秒为单位(避免由于设备离线导致的报告延迟)。 + - `"source_registration_time"` + - : 一个字符串,表示从 Unix 纪元到归因来源注册的时间,四舍五入到整天。 + - `"version"` + - : 一个表示生成报告的 API 版本的字符串。 +- `"aggregation_service_payloads"` + + - : 一个对象数组,表示汇总服务用来组装报告中数据的直方图贡献的有效负载对象。目前,每个报告只支持一个由浏览器配置的有效负载。将来可能会支持多个可定制的有效负载。每个有效负载对象包含以下属性: + + - `"payload"` + + - : 一个通过 [HPKE](https://datatracker.ietf.org/doc/rfc9180/) 加密并经过 [base64](/zh-CN/docs/Glossary/Base64) 编码的 [CBOR](https://cbor.io/) 映射,结构如下: + + ```js + { + "operation": "histogram", // 允许服务支持将来其他操作 + "data": [{ + "bucket": <分桶,编码为 16 字节(即 128 位)的大端字节串>, + "value": <桶值,编码为 4 字节(即 32 位)的大端字节串> + }, ...] + } + ``` + + - `"key_id"` + - : 一个字符串,标识用于加密有效负载的公钥。 + - `"debug_cleartext_payload"` {{optional_inline}} + - : 可选的调试信息。 + +- `"aggregation_coordinator_origin"` + - : 汇总服务的部署选项。 +- `"source_debug_key"` {{optional_inline}} + - : 一个 64 位无符号整数,表示归因来源的调试密钥。此值与相关 {{httpheader("Attribution-Reporting-Register-Source")}} 标头的 [`"debug_key"`](/zh-CN/docs/Web/HTTP/Headers/Attribution-Reporting-Register-Source#debug_key) 字段中的值一致。更多信息请参见[调试报告](#调试报告)。 +- `"trigger_debug_key"` {{optional_inline}} + - : 一个 64 位无符号整数,表示归因触发器的调试密钥。此值与相关 {{httpheader("Attribution-Reporting-Register-Trigger")}} 标头的 `"debug_key"` 字段中的值一致。更多信息请参见[调试报告](#调试报告)。 + +## 为报告添加噪声 + +噪声被添加到报告中,以模糊与特定来源相关的输出,从而保护用户隐私。确切的来源数据无法被识别并归因到用户个体,但从数据中提取的总体模式仍然可以提供相同的意义。 + +关于归因报告中噪声的工作原理,请参见: + +- [理解汇总报告中的噪声](https://developers.google.com/privacy-sandbox/private-advertising/attribution-reporting/understanding-noise) +- [数据限制和噪声](https://github.com/WICG/attribution-reporting-api/blob/main/EVENT.md#data-limits-and-noise) +- [处理噪声](https://developers.google.com/privacy-sandbox/private-advertising/attribution-reporting/working-with-noise) + +## 报告优先级和限制 + +默认情况下,所有归因来源的优先级相同,并且归因模型是最后接触(last-touch)模型,这意味着转化被归因到最新的匹配来源事件。对于事件级和可汇总的报告,你可以通过在相关 {{httpheader("Attribution-Reporting-Register-Source")}} 标头中设置 `"priority"` 字段的新值来更改来源优先级。默认值为 `0`;如果你将特定来源的 `"priority"` 值设置为 `1`,则该来源将首先匹配,优先于任何优先级为 `0` 的来源。优先级为 `2` 的来源将在优先级为 `1` 的来源之前匹配,依此类推。 + +归因触发器优先级的工作方式相同;你也可以通过在相关 {{httpheader("Attribution-Reporting-Register-Trigger")}} 标头中添加 `"priority"` 字段来设置触发器优先级,但仅适用于事件级报告。 + +不同的来源类型有不同的默认限制: + +- [基于导航的归因来源](/zh-CN/docs/Web/API/Attribution_Reporting_API/Registering_sources#基于导航的归因来源)默认限制为三个报告。例如,如果用户点击了一个广告并进行了四次转化:他们访问了广告商网站主页,然后访问了产品页面,注册了时事通讯,最后进行了购买。由于这是第四次转化,购买报告将被丢弃。 +- [基于事件的归因来源](/zh-CN/docs/Web/API/Attribution_Reporting_API/Registering_sources#基于事件的归因来源)默认限制为一个报告。 + +> [!NOTE] +> 可以通过在关联的 `Attribution-Reporting-Register-Source` 标头的 `"event_report_windows"` 字段中设置不同的 `"end_times"` 来调整报告限制。 + +当为给定的来源事件触发归因时,如果该来源已达到最大归因次数(点击为 3 次,图像/脚本为 1 次),浏览器将: + +- 将新报告的优先级与同一来源的现有计划报告的优先级进行比较。 +- 删除优先级最低的报告以安排新的报告。如果新报告的优先级最低,则忽略新报告,不会收到它。 + +如果未设置优先级,浏览器将回退到其默认行为:在点击后的第三次转化或查看后的第一次转化后发生的任何转化都将被丢弃。 + +## 过滤器 + +你可以使用过滤器定义哪些转化会生成报告。例如,你可以选择只计算特定产品类别的转化,并过滤掉其他类别的转化。 + +要声明过滤器: + +1. 在来源注册时,将 `filter_data` 字段添加到 {{httpheader("Attribution-Reporting-Register-Source")}} 标头中,该字段定义了你将在触发端用于过滤转化的过滤键。这些是完全自定义的字段。例如,要指定仅特定子域名和特定产品的转化: + + ```json + "filter_data": { + "conversion_subdomain": ["electronics.megastore", "electronics2.megastore"], + "product": ["1234"] + } + ``` + +2. 在触发注册时,将 `filters` 字段添加到 {{httpheader("Attribution-Reporting-Register-Trigger")}} 标头中。例如,以下内容会使触发交互匹配上述来源注册,因为它们都包含 `"electronics.megastore"` 的 `"conversion_subdomain"` 字段。而 `"directory"` 过滤器则在尝试匹配时被忽略,因为它未包含在上述来源注册中。 + + ```json + "filters": { + "conversion_subdomain": ["electronics.megastore"], + "directory": ["/store/electronics"] + } + ``` + +如果 `"filter_data"` 和 `"filters"` 字段包含匹配的子字段(如上例中的 `"conversion_subdomain"`),但这些子字段的值没有匹配项,则会忽略触发器,导致没有匹配。 + +### 过滤触发数据 + +可以扩展 {{httpheader("Attribution-Reporting-Register-Trigger")}} 标头中的 `event_trigger_data` 字段,以根据在 {{httpheader("Attribution-Reporting-Register-Source")}} 标头中定义的 `filter_data` 选择性地设置 `trigger_data`、`priority` 或 `deduplication_key`。 + +例如: + +```json +{ + "event_trigger_data": [ + { + "trigger_data": "2", + "filters": { "source_type": ["navigation"] } + }, + { + "trigger_data": "1", + "filters": { "source_type": ["event"] } + } + ] +} +``` + +> **备注:** `"source_type"` 是在来源的 `"filter_data"` 上自动填充的字段。 + +> **备注:** `not_filters`,即否定过滤器,也受支持。 + +在此上下文中,`filters` 可以是对象或对象数组。当指定列表时,只需一个字典匹配即可将触发器视为匹配。 + +```json +{ + "event_trigger_data": [ + { + "trigger_data": "2", + "filters": [ + { + "product": ["1234"], + "conversion_subdomain": ["electronics.megastore"] + }, + { + "product": ["4321"], + "conversion_subdomain": ["electronics4.megastore"] + } + ] + } + ] +} +``` + +如果事件触发器的过滤器都不匹配,则不会创建事件级报告。如果过滤器匹配多个事件触发器,则使用第一个匹配的事件触发器。 + +## 调试报告 + +你可以启用调试报告,以返回有关归因报告的故障排除信息。这些报告可用于检查你的设置是否正常工作,并了解基于 cookie 的旧实现和新归因报告实现之间的测量结果差距。调试报告会立即发送;它们不受事件级和汇总报告相同的调度约束。 + +有两种不同类型的调试报告: + +- **成功调试报告**跟踪特定归因报告的成功生成。成功调试报告在注册相应触发器后立即生成并发送。 +- **详细调试报告**为与归因报告关联的归因来源和归因触发事件提供更多可见性。它们使你能够确保来源已成功注册,或跟踪丢失的报告并确定其原因(例如,由于来源或触发事件注册失败或发送或生成报告时失败)。详细调试报告在来源或触发器注册时立即发送。 + +> [!NOTE] +> 要使用调试报告,报告来源(origin)需要设置 cookie。如果配置为接收报告的来源是第三方,则该 cookie 将是[第三方 cookie](/zh-CN/docs/Web/Privacy/Third-party_cookies),这意味着在禁用/不可用第三方 cookie 的浏览器中将无法使用调试报告。 + +### 使用调试报告 + +要使用调试报告,你需要: + +1. 在报告来源上设置 `ar_debug` cookie。在来源和触发注册期间,该 cookie 需要存在: + + ```http + Set-Cookie: ar_debug=1; SameSite=None; Secure; Path=/; HttpOnly + ``` + +2. 在与你希望为其公开调试信息的归因报告相关的所有 {{httpheader("Attribution-Reporting-Register-Source")}} 和 {{httpheader("Attribution-Reporting-Register-Trigger")}} 响应标头中设置 `debug_key` 字段。每个 `debug_key` 值必须是格式为十进制字符串的 64 位无符号整数。使每个调试键成为唯一的 ID——例如,可以将每个键设置为 cookie ID + 来源/触发时间戳(如果希望将其与旧的基于 cookie 的系统进行比较,则可以在旧系统中捕获相同的时间戳)。 + + ```json + { + "debug_key": "647775351539539" + } + ``` + + > [!NOTE] + > 使来源端的调试键与 `source_event_id` 不同,以便区分具有相同来源事件 ID 的单个报告。 + +3. 可选地,在 `Attribution-Reporting-Register-Source` 和 `Attribution-Reporting-Register-Trigger` 标头中将 `debug_reporting` 字段设置为 `true`。如果执行此操作,将生成详细的调试报告。如果不执行此操作,将生成反映你正在生成的归因报告类型(事件级或汇总)的成功调试报告。 + + ```json + { + "debug_key": "647775351539539", + "debug_reporting": true + } + ``` + +4. 设置适当的端点以接收你希望生成的调试报告。调试报告发送到报告来源中的三个单独端点: + + - 事件级成功调试报告的端点:`/.well-known/attribution-reporting/debug/report-event-attribution` + - 汇总成功调试报告的端点:`/.well-known/attribution-reporting/debug/report-aggregate-attribution` + - 详细调试报告的端点:`/.well-known/attribution-reporting/debug/verbose` + +生成的成功调试报告与归因报告相同,并包含来源端和触发器端的调试键(分别位于 `"source_debug_key"` 和 `"trigger_debug_key"` 字段中)。 + +有关更多信息和示例,请参见: + +- developers.google.com 上的[调试报告介绍](https://developers.google.com/privacy-sandbox/private-advertising/attribution-reporting/attribution-reporting-debugging/)(2023) +- developers.google.com 上的[设置调试报告](https://developers.google.com/privacy-sandbox/private-advertising/attribution-reporting/attribution-reporting-debugging/part-2/)(2023) +- developers.google.com 上的[调试宝典](https://developers.google.com/privacy-sandbox/private-advertising/attribution-reporting/attribution-reporting-debugging/part-3/)(2023) diff --git a/files/zh-cn/web/api/attribution_reporting_api/index.md b/files/zh-cn/web/api/attribution_reporting_api/index.md new file mode 100644 index 00000000000000..22dc0fa6fb70c8 --- /dev/null +++ b/files/zh-cn/web/api/attribution_reporting_api/index.md @@ -0,0 +1,117 @@ +--- +title: 归因报告 API +slug: Web/API/Attribution_Reporting_API +l10n: + sourceCommit: f430d277573ba0b06b1ac33ae8017fd90f170bef +--- + +{{SeeCompatTable}}{{securecontext_header}}{{DefaultAPISidebar("Attribution Reporting API")}} + +**归因报告 API**(Attribution Reporting API)使开发者能够衡量转化——比如当用户点击嵌入在某个网站上的广告,然后在供应商的网站上购买商品——并随后访问这些转化的报告。它在不依赖第三方跟踪 cookie 的情况下完成这一过程。 + +## 概念和用法 + +广告主通常希望衡量有多少用户看到了广告后,接着查看并购买了产品(转化)。这使他们能够了解哪些广告投放带来了最大的投资回报率(ROI),从而可以相应地调整他们的广告策略。衡量转化的过程通常包括捕捉以下数据: + +- 哪些用户进行了转化(例如购买了商品或注册了服务),以及转化的数量。 +- 他们所在的地理区域。 +- 广告投放的位置。 +- 销售了多少产品、注册了多少服务等。 +- 产生了多少收入。 + +传统上,Web 上的转化测量依赖于第三方跟踪 cookie。广告通常嵌入在网页的一个 {{htmlelement("iframe")}} 中,这样可以设置一个包含用户及其与广告互动信息的 cookie。 + +之后,当用户决定访问广告主的网站时,只要该网站来自与广告相同的域名,该网站就可以访问之前由广告设置的第三方 cookie。广告主可以将广告的数据与自己的第一方数据关联起来,以回答诸如“用户在与另一个网站的产品广告互动后是否购买了该产品?”的问题。 + +这对用户[隐私](/zh-CN/docs/Web/Privacy)不友好。在这种情况下,来自相同域名的任何页面都可以访问该 cookie,以及嵌入这些页面的网站的信息。许多方可以访问这些数据,并根据用户的浏览习惯推测其他数据。 + +归因报告 API 提供了一种保护用户隐私的广告转化测量方式。 + +### 它是如何工作的? + +让我们通过一个例子来说明归因报告 API 的工作原理。 + +假设我们有一个在线商店 `shop.example`(即广告主),它在一个内容网站 `news.example`(即发布者)上嵌入了一个关于其产品的广告。广告内容位于 `ad.shop.example`。 + +在线商店的拥有者希望衡量从与广告互动、查看其网站上的产品页面并将产品放入购物车的用户那里获得多少转化。 + +![下面图像表示了描述的步骤](ara-flow.png) + +涉及的步骤如下: + +1. 当用户访问 `news.example` 网站时,可以为与嵌入广告的特定用户交互注册一个**归因来源**。用户可以通过多种方式与页面上的广告互动。为了使广告交互注册归因来源,广告必须发送一个带有 {{httpheader("Attribution-Reporting-Eligible")}} 标头的请求,以表明响应有资格注册归因来源。如果响应中包含适当的 {{httpheader("Attribution-Reporting-Register-Source")}} 标头,则完成归因来源的注册。归因来源可以是,例如: + - 一个链接。在这种情况下,交互是用户点击链接(直接通过 {{htmlelement("a")}} 元素,或通过 {{domxref("Window.open()")}} 调用)。通过对导航请求的响应来注册来源。 + - 一张图片,例如广告横幅或 1x1 透明跟踪像素。在这种情况下,交互是用户访问页面。图片加载时,即服务器响应图片请求时,注册来源。 + - 一个 fetch 请求(即 {{domxref("Window/fetch", "fetch()")}} 或 {{domxref("XMLHttpRequest")}})。在这种情况下,交互可以根据你的应用程序的需要进行指定——例如,fetch 请求可以由 `click` 或 `submit` 事件触发。来源在响应返回时注册。 +2. 当归因来源交互发生时,{{httpheader("Attribution-Reporting-Register-Source")}} 标头中返回的来源数据会存储在仅浏览器可访问的私有本地缓存中。此数据包括页面和广告主可用的上下文和第一方数据、收集转化数据的广告技术公司的来源以及一个或多个期望从该广告发生转化的目标([eTLD+1](/zh-CN/docs/Glossary/eTLD))(即广告主的网站,例如 `shop.example`)。 +3. 当用户稍后访问 `shop.example` 时,当交互指示转化发生时,该网站可以注册一个**归因触发器**(例如,用户点击 `shop.example` 上的“添加到购物车”按钮)。浏览器将发送一个带有 {{httpheader("Attribution-Reporting-Eligible")}} 标头的请求,以表明响应有资格注册归因触发器,如果响应中包含适当的 {{httpheader("Attribution-Reporting-Register-Trigger")}} 标头,则完成注册。归因触发器可以是,例如: + - 一张图片,例如购物车图标或 1x1 透明跟踪像素。在这种情况下,交互是用户访问页面。触发器在图片加载时注册,即当服务器响应图片请求时。 + - 一个 fetch 请求(即 {{domxref("Window/fetch", "fetch()")}} 或 {{domxref("XMLHttpRequest")}})。在这种情况下,交互可以根据你的应用程序的需要进行指定——例如,fetch 请求可以由 `click` 或 `submit` 事件触发。触发器在响应返回时注册。 +4. 当触发器归因完成后,浏览器会尝试将 [Attribution-Reporting-Register-Trigger](/zh-CN/docs/Web/HTTP/Headers/Attribution-Reporting-Register-Trigger) 标头中的数据与私有本地缓存中保存的来源数据条目进行匹配(见第 2 步)。有关匹配方法和要求,请参阅[注册归因触发器](/zh-CN/docs/Web/API/Attribution_Reporting_API/Registering_triggers)。 +5. 如果找到匹配,浏览器将把报告数据发送到通常由广告技术提供商拥有的报告服务器上的端点,在那里可以安全地进行分析。与 cookie 不同,这些数据仅对你发送数据的特定网站可用——不会在其他地方共享数据。这些报告可以是: + - **事件级报告**:基于归因来源事件的报告,其中详细的来源数据与粗略的触发器数据相关联。例如,报告可能看起来像“`ad.shop.example` 上的点击 ID 200498 导致了 `shop.example` 的购买”,其中“点击 ID 200498”是详细的来源数据,“购买”是粗略的触发器数据。详细的来源数据可能包含来源页面的第一方或上下文数据,而触发器数据可能编码来自触发器页面的事件。 + - **汇总报告**:更详细的报告,结合来自来源和触发器侧的多个转化数据。例如“`news.example` 上的广告活动 ID 774653 导致了 `shop.example` 上来自意大利用户的 654 笔销售,总收入为 $9540。”汇总报告的编制需要使用聚合服务(例如 [Google 聚合服务](https://github.com/privacysandbox/aggregation-service))。 + +有关实现上述步骤所需功能的更多信息,请参阅: + +1. [注册归因来源](/zh-CN/docs/Web/API/Attribution_Reporting_API/Registering_sources) +2. [注册归因触发器](/zh-CN/docs/Web/API/Attribution_Reporting_API/Registering_triggers) +3. [生成报告](/zh-CN/docs/Web/API/Attribution_Reporting_API/Generating_reports) + +## 接口 + +归因报告 API 并未定义任何独立的接口。 + +### 其他接口的扩展 + +- {{domxref("HTMLAnchorElement.attributionSrc")}}、{{domxref("HTMLImageElement.attributionSrc")}}、{{domxref("HTMLScriptElement.attributionSrc")}} + - : `attributionSrc` 属性允许你以编程方式获取和设置 {{htmlelement("a")}}、{{htmlelement("img")}}、和 {{htmlelement("script")}} 元素上的 `attributionsrc` 属性。它反映了该属性的值。 +- {{domxref("Window/fetch", "fetch()")}} 和 {{domxref("Request.Request", "Request()")}} 构造函数中的 `attributionReporting` 选项 + - : 当通过 {{domxref("Window/fetch", "fetch()")}} 生成请求时,这表示你希望响应能够注册归因来源或触发器。 +- {{domxref("XMLHttpRequest.setAttributionReporting()")}} + - : 当通过 {{domxref("XMLHttpRequest")}} 生成请求时,这表示你希望响应能够注册归因来源或触发器。 +- {{domxref("Window.open()")}} 中的 `attributionsrc` 特性关键字 + - : 当 `open()` 方法完成时,完成归因来源的注册*并*触发浏览器存储相关的来源数据(如 {{httpheader("Attribution-Reporting-Register-Source")}} 响应标头中提供的)。请注意,`Window.open()` 调用不能用于注册归因触发器。 + +## HTML 元素 + +- {{htmlelement("a")}}、{{htmlelement("img")}} 和 {{htmlelement("script")}}——`attributionsrc` 属性 + - : 指定你希望浏览器在相关资源请求中发送 {{httpheader("Attribution-Reporting-Eligible")}} 标头。在服务器端,此标头用于触发发送 {{httpheader("Attribution-Reporting-Register-Source")}} 或 {{httpheader("Attribution-Reporting-Register-Trigger")}} 响应标头。当注册归因来源时,这是必需的;当注册归因触发器时,只有在你希望指定与 `src` 属性指向的资源不同的注册服务器时才需要。请注意,`` 元素不能用于注册归因触发器。 + +## HTTP 标头 + +- {{httpheader("Attribution-Reporting-Eligible")}} + - : 表示相应响应有资格注册归因来源或触发器的 HTTP 请求。 +- {{httpheader("Attribution-Reporting-Register-Source")}} + - : 注册页面特性作为归因来源的 HTTP 响应。这作为对包含 `Attribution-Reporting-Eligible` 标头的请求的响应的一部分。 +- {{httpheader("Attribution-Reporting-Register-Trigger")}} + - : 注册页面特性作为归因触发器的 HTTP 响应。这作为对包含 `Attribution-Reporting-Eligible` 标头的请求的响应的一部分。 +- {{httpheader("Permissions-Policy")}} {{httpheader('Permissions-Policy/attribution-reporting','attribution-reporting')}} 指令 + - : 控制当前文档是否被允许使用归因报告。 + +## 注册和本地测试 + +要在你的网站上使用归因报告 API,你必须在[隐私沙盒注册过程](/zh-CN/docs/Web/Privacy/Privacy_sandbox/Enrollment)中指定它。如果不这样做,API 流程将在响应时被阻止,即响应标头将被忽略,来源和触发器将不会被注册。 + +你仍然可以在没有注册的情况下本地测试你的归因报告 API 代码。要允许本地测试,请启用以下 Chrome 开发者标志: + +`chrome://flags/#privacy-sandbox-enrollment-overrides` + +## 示例 + +请参阅[演示:归因报告 API](https://arapi-home.web.app/) 以获取示例实现(也可查看[源代码](https://github.com/GoogleChromeLabs/trust-safety-demo/tree/main/attribution-reporting))。 + +## 规范 + +{{Specifications}} + +## 浏览器兼容性 + +{{Compat}} + +## 参见 + +- [归因报告标头验证工具](https://wicg.github.io/attribution-reporting-api/validate-headers) +- developers.google.com 上的[归因报告](https://developers.google.com/privacy-sandbox/private-advertising/attribution-reporting/)(2023) +- developers.google.com 上的[启用转化测量](https://developers.google.com/privacy-sandbox/private-advertising/attribution-reporting/enable-conversion-measurement)(2023) +- developers.google.com 上的[隐私沙盒](https://developers.google.com/privacy-sandbox/)(2023) diff --git a/files/zh-cn/web/api/attribution_reporting_api/registering_sources/index.md b/files/zh-cn/web/api/attribution_reporting_api/registering_sources/index.md new file mode 100644 index 00000000000000..a29cfa83d150b3 --- /dev/null +++ b/files/zh-cn/web/api/attribution_reporting_api/registering_sources/index.md @@ -0,0 +1,287 @@ +--- +title: 注册归因来源 +slug: Web/API/Attribution_Reporting_API/Registering_sources +l10n: + sourceCommit: ec1006afdf68a5808a48ab6301f9ccff3cd7ecc2 +--- + +{{SeeCompatTable}}{{DefaultAPISidebar("Attribution Reporting API")}} + +本文解释了如何在使用[归因报告 API](/zh-CN/docs/Web/API/Attribution_Reporting_API) 时注册归因来源。 + +## 基本方法 + +归因来源的形式包括链接、图片或脚本,它们会被包含在你想要衡量交互行为的内容中(例如,想要衡量转化的广告)。当发生特定用户交互时,浏览器会将来源数据存储在一个私有的本地缓存中(仅浏览器可访问)。不同的归因来源类型有不同的注册和信号交互方式,它们可以分为以下几类: + +- 导航来源,指浏览器在响应导航时存储源数据。例如,当用户点击链接或用键盘激活它时,或者通过 {{domxref("Window.open()")}} 调用发生导航时。有关示例,请参见[基于导航的归因来源](#基于导航的归因来源)。 +- 事件来源,指浏览器在事件触发时存储源数据。有关示例,请参见[基于事件的归因来源](#基于事件的归因来源)。 + +注册来源和检索、存储来源数据的过程在这两种情况下是相同的: + +1. 当用户与归因来源进行交互时,它会在请求中发送 {{httpheader("Attribution-Reporting-Eligible")}} 标头给测量交互的服务器(通常是广告主的服务器),以表明响应有资格注册来源。例如: + + ```http + Attribution-Reporting-Eligible: navigation-source + ``` + +2. 当服务器接收到包含 `Attribution-Reporting-Eligible` 标头的请求时,它可以在响应中包含 {{httpheader("Attribution-Reporting-Register-Source")}} 标头以完成来源注册。其值是一个 JSON 字符串,提供了浏览器应存储的有关与之交互的归因来源的信息。该标头中包含的信息还决定了浏览器生成哪些类型的报告: + + - 以下示例将导致在[触发器](/zh-CN/docs/Web/API/Attribution_Reporting_API/Registering_triggers)与来源匹配时生成一个[事件级报告](/zh-CN/docs/Web/API/Attribution_Reporting_API/Generating_reports#事件级报告): + + ```js + res.set( + "Attribution-Reporting-Register-Source", + JSON.stringify({ + source_event_id: "412444888111012", + destination: "https://advertiser.example", + trigger_data: [0, 1, 2, 3, 4], + trigger_data_matching: "exact", + expiry: "604800", + priority: "100", + debug_key: "122939999", + event_report_window: "86400", + }), + ); + ``` + + 在这种情况下,唯一必需的字段是 `destination`,它指定 1–3 个触发器预期触发的站点。它们用于在与触发器交互时将归因触发器与来源进行匹配。上述指定的其他字段如下: + + - `"source_event_id"`:一个表示归因来源的 ID 的字符串,可以用于在归因来源被交互时将其映射到其他信息,或在报告端点(见[生成报告 > 基本流程](/zh-CN/docs/Web/API/Attribution_Reporting_API/Generating_reports#基本流程)获取端点信息)聚合信息。 + - `"trigger_data"`:一个 32 位无符号整数数组,表示可能匹配此来源的不同触发事件的数据。例如,“用户将商品添加到购物车”或“用户注册了邮件列表”可以是触发站点上发生的事件,这些事件可以匹配此来源并表示广告主试图衡量的某种转化。它们必须与[触发器](/zh-CN/docs/Web/HTTP/Headers/Attribution-Reporting-Register-Trigger#trigger_data)中指定的 `"trigger_data"` 匹配,以便进行事件级归因。 + > [!NOTE] + > 用于表示每个事件的值,以及数组中的元素数量,都是完全任意的,由作为开发者的你定义。数组中可以包含未使用的值,但必须存在值,以便浏览器在触发器注册时将其归因于来源。 + - `"trigger_data_matching"`:一个字符串,指定如何将触发器的 `"trigger_data"` 与来源的 `"trigger_data"` 匹配。`"exact"` 是你几乎总是会使用的值,它匹配精确值。 + - `"expiry"`:一个表示归因来源过期时间的字符串,以秒为单位,过期后该源将不再有效(即,后续触发器将无法归因到此来源)。 + - `"priority"`:一个表示归因来源优先级的字符串值。有关更多信息,请参见[报告优先级和限制](/zh-CN/docs/Web/API/Attribution_Reporting_API/Generating_reports#报告优先级和限制)。 + - `"debug_key"`:一个以十进制格式表示的 64 位无符号整数,表示调试密钥。如果你希望生成一个[调试报告](/zh-CN/docs/Web/API/Attribution_Reporting_API/Generating_reports#调试报告)以配合关联的归因报告,则设置此项。 + - `"event_report_window"`:一个表示时间的字符串(以秒为单位),在此时间后,后续触发器将无法归因到此来源(以生成事件级报告)。 + + 参见 {{httpheader("Attribution-Reporting-Register-Source")}} 以获取此标头中所有可用字段的详细描述。 + + - 要使浏览器在触发器匹配到来源时生成[汇总报告](/zh-CN/docs/Web/API/Attribution_Reporting_API/Generating_reports#汇总报告),需要在生成事件级报告所需的字段*之外*,额外包含一些字段。 + + ```js + res.set( + "Attribution-Reporting-Register-Source", + JSON.stringify({ + source_event_id: "412444888111012", + destination: "https://advertiser.example", + trigger_data: [0, 1, 2, 3, 4], + trigger_data_matching: "exact", + expiry: "604800", + priority: "100", + debug_key: "122939999", + event_report_window: "86400", + + aggregation_keys: { + campaignCounts: "0x159", + geoValue: "0x5", + }, + aggregatable_report_window: "86400", + }), + ); + ``` + + 在此示例中,额外的字段包括: + + - `"aggregation_keys"`:一个包含用户提供的键的对象,表示在生成的报告值下汇总不同数据点。 + - `"aggregatable_report_window"`:一个表示时间的字符串(以秒为单位),在此时间后,触发数据将不再包含在生成的可汇总报告中。 + + 同样,请参见 {{httpheader("Attribution-Reporting-Register-Source")}} 以获取此标头中所有字段的详细描述。 + +3. 成功注册来源后,浏览器将提供的来源数据存储在其私有本地缓存中。 + +## 基于导航的归因来源 + +导航来源对于测量与链接的交互非常有用——例如,用户可能在发布者页面上看到广告,然后点击它以导航到希望发生转化的广告主的页面。 + +有几种不同类型的基于导航的归因来源(例如,点击广告)可以注册——基于 HTML 的(使用 `attributionsrc` 属性)和基于 {{domxref("Window.open()")}} 调用的(使用 `attributionsrc` 窗口特性)。 + +### 基于 HTML 的导航来源 + +要注册基于导航的归因来源,你可以将 `attributionsrc` 属性添加到适当的 {{htmlelement("a")}} 元素中,这指定了注册请求将被发送到的位置。 + +如果你将属性值留空,则注册请求将发送到链接到的位置。也可以在值中指定一个或多个额外的 URL 以发送注册请求;有关详细信息,请参见[在 attributionsrc 中指定 URL](#在_attributionsrc_中指定_url)。 + +`attributionsrc` 可以通过声明的方式添加: + +```html + + 点击访问我们的商店 + +``` + +或者通过 {{domxref("HTMLAnchorElement.attributionSrc")}} 属性: + +```js +const aElem = document.querySelector("a"); +aElem.attributionSrc = ""; +``` + +在这种情况下,交互发生时,浏览器在用户点击链接并且浏览器接收到响应时,会存储与基于导航的归因来源(如在 {{httpheader("Attribution-Reporting-Register-Source")}} 响应标头中提供的)相关的来源数据。 + +### 基于 Window.open() 的导航来源 + +你还可以将 `attributionsrc` 特性关键字添加到 {{domxref("Window.open()")}} 调用的特性属性中。在此示例中,我们在响应 `click` 事件时运行它: + +```js +elem.addEventListener("click", () => { + window.open("https://shop.example", "targetWindow", "attributionsrc"); +}); +``` + +> [!NOTE] +> 在设置像上面示例中的 [`click`](/zh-CN/docs/Web/API/Element/click_event) 事件时,建议将其设置在预期会点击的控件上,例如 {{htmlelement("button")}} 或 {{htmlelement("a")}} 元素上。这在语义上更合理,并且对屏幕阅读器和键盘用户更友好。 + +> [!NOTE] +> 要通过 `open()` 注册归因来源,必须在[瞬态激活](/zh-CN/docs/Glossary/Transient_activation)(即用户交互事件处理程序内部,如 `click`)中调用,并且必须在用户交互后的五秒内完成。 + +## 基于事件的归因来源 + +基于事件的归因来源会在某些事件——例如在 `` 或 `