首页指南参考教程

Expo 更新 v1

版本 1


介绍

¥Introduction

这是 Expo Updates 的规范,该协议用于向在多个平台上运行的 Expo 应用提供更新。

¥This is the specification for Expo Updates, a protocol for delivering updates to Expo apps running on multiple platforms.

一致性

¥Conformance

合格的服务器和客户端库必须满足所有规范要求。本文档通过描述性断言和具有明确定义含义的关键词来描述一致性要求。

¥Conforming servers and client libraries must fulfill all normative requirements. Conformance requirements are described in this document by both descriptive assertions and key words with clearly defined meanings.

本文档规范部分中的关键字 "MUST"、"MUST NOT"、"REQUIRED"、"SHALL"、"SHALL NOT"、"SHOULD"、"SHOULD NOT"、"RECOMMENDED"、"MAY" 和 "OPTIONAL" 应按照 IETF RFC 2119 中的描述进行解释。这些关键词可能以小写形式出现,并且仍然保留其含义,除非明确声明为非规范。

¥The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative portions of this document are to be interpreted as described in IETF RFC 2119. These key words may appear in lowercase and still retain their meaning unless explicitly declared as non-normative.

该协议的一致实现可以提供附加功能,但不得明确禁止,否则会导致不一致性。在相关的情况下,符合要求的客户端应允许并忽略未知字段。

¥A conforming implementation of this protocol MAY provide additional functionality, but MUST NOT where explicitly disallowed or would otherwise result in non-conformance. Where relevant, unknown fields should be allowed and ignored by conforming clients.

概述

¥Overview

符合要求的服务器和客户端库必须遵循 RFC 7231 中描述的 HTTP 规范以及本规范中描述的更精确的指导。

¥Conforming servers and client libraries MUST follow the HTTP spec as described in RFC 7231 as well as the more precise guidance described in this spec.

  • 更新被定义为 manifest 以及清单中引用的资源。

    ¥An update is defined as a manifest together with the assets referenced inside the manifest.

  • directive 被定义为来自服务器的消息,指示客户端执行操作。

    ¥A directive is defined as a message from the server that instructs clients to perform an action.

Expo Updates 是一种用于向客户端组装和交付更新和指令的协议。

¥Expo Updates is a protocol for assembling and delivering updates and directives to clients.

该规范的主要受众是 Expo 应用服务和希望管理自己的更新服务器以满足内部需求的组织。

¥The primary audiences of this spec are Expo Application Services and organizations that wish to manage their own update server to satisfy internal requirements.

客户端

¥Client

参见 参考客户库

¥See the reference client library.

运行符合 Expo Updates 客户端库的应用必须加载客户端库更新数据库中保存的最新更新,可能是在按更新清单 metadata 的内容进行过滤之后。

¥An app running a conformant Expo Updates client library MUST load the most recent update saved in the client library's update database, possibly after filtering by the contents of the update's manifest metadata.

下面描述了一致的 Expo Updates 客户端库必须如何从一致的服务器检索新的更新:

¥The following describes how a conformant Expo Updates client library MUST retrieve a new update from a conformant server:

  1. 客户端库必须为最近的更新和指令创建 request,并在标头中指定约束。

    ¥The client library MUST make a request for the most recent update and directive, with constraints specified in the headers.

  2. 如果收到 response,客户端库必须处理其内容:

    ¥If a response is received, the client library MUST process its contents:

    • 对于包含更新的响应,客户端库应继续发出额外的请求来下载和存储清单中指定的任何新资源。清单和资源一起被视为新的更新。客户端库将编辑其本地状态以反映新更新已添加到本地存储。它还将使用响应 headers 中找到的新 expo-manifest-filtersexpo-server-defined-headers 更新本地状态。

      ¥For a response containing an update, the client library SHALL proceed to make additional requests to download and store any new assets specified in the manifest. The manifest and assets together are considered a new update. The client library will edit its local state to reflect that a new update has been added to the local storage. It will also update the local state with the new expo-manifest-filters and expo-server-defined-headers found in the response headers.

    • 对于包含指令的响应,客户端库将根据指令类型使用该指令并相应地编辑其本地状态。

      ¥For a response containing a directive, the client library will consume the directive depending on the directive type and edit its local state accordingly.

要求

¥Request

符合要求的客户端库必须发出带有标头的 GET 请求:

¥A conformant client library MUST make a GET request with the headers:

  1. expo-protocol-version: 1,指定此 Expo 更新规范的版本 1。

    ¥expo-protocol-version: 1, to specify version 1 of this Expo Updates specification.

  2. expo-platform,指定客户端运行的平台类型。

    ¥expo-platform, to specify the platform type the client is running on.

    • iOS 必须是 expo-platform: ios

      ¥iOS MUST be expo-platform: ios.

    • Android 必须是 expo-platform: android

      ¥Android MUST be expo-platform: android.

    • 如果不是这些平台之一,服务器应该返回 400 或 404

      ¥If it is not one of these platforms, the server SHOULD return a 400 or a 404

  3. expo-runtime-version 必须是与客户端兼容的运行时版本。运行时版本规定客户端正在运行的原生代码设置。它应该在构建客户端时设置。例如,在 iOS 客户端中,该值可以在 plist 文件中设置。

    ¥expo-runtime-version MUST be a runtime version compatible with the client. A runtime version stipulates the native code setup a client is running. It should be set when the client is built. For example, in an iOS client, the value may be set in a plist file.

  4. 先前响应的 服务器定义的标头 规定的任何标头。

    ¥Any headers stipulated by a previous responses' server defined headers.

一致的客户端库可以基于 支持的响应结构 发送 accept: application/expo+jsonaccept: application/jsonaccept: multipart/mixed 之一,但它应该发送 accept: application/expo+json, application/json, multipart/mixed。一致的客户端库可以使用 RFC 7231 中指定的 "q" 参数来表达偏好,默认为 1

¥A conformant client library MAY send one of accept: application/expo+json, accept: application/json, or accept: multipart/mixed based on the supported response structures, though it SHOULD send accept: application/expo+json, application/json, multipart/mixed. A conformant client library MAY express preference using "q" parameters as specified in RFC 7231, which default to 1.

配置为执行 代码签名 验证的一致客户端库必须发送 expo-expect-signature 标头,以指示它期望一致服务器在清单响应中包含 expo-signature 标头。expo-expect-signatureExpo SFV 字典,可以包含以下任意键值对:

¥A conformant client library configured to perform code signing verification MUST send a expo-expect-signature header to indicate that it expects the conformant server to include the expo-signature header in the manifest response. expo-expect-signature is an Expo SFV dictionary which MAY contain any of the following key value pairs:

  • sig 应包含布尔值 true 以指示它需要一致的服务器以 sig 密钥中的签名进行响应。

    ¥sig SHOULD contain the boolean true to indicate that it requires a conformant server to respond with the signature in the sig key.

  • keyid 应包含客户端将用于验证签名的公钥的 keyId

    ¥keyid SHOULD contain the keyId of the public key the client will use to verify the signature

  • alg 应包含客户端将用于验证签名的算法

    ¥alg SHOULD contain the algorithm the client will use to verify the signature

示例:

¥Example:

expo-protocol-version: 1
accept: application/expo+json;q=0.9, application/json;q=0.8, multipart/mixed
expo-platform: *
expo-runtime-version: *
expo-expect-signature: sig, keyid="root", alg="rsa-v1_5-sha256"

响应

¥Response

符合标准的服务器必须返回至少采用以下两种响应结构之一构造的响应,可以支持其中一种或两种响应结构,并且当请求不支持的响应结构时,服务器应该以 HTTP 406 错误状态进行响应。希望以与所请求协议版本不兼容的响应进行响应的服务器也应该以 HTTP 406 错误状态进行响应。

¥A conformant server MUST return a response structured in at least one of the two following response structures, MAY support either or both response structures, and when an unsupported response structure is requested the server SHOULD respond with an HTTP 406 error status. A server that wishes to respond with an incompatible response for the requested protocol version SHOULD also respond with an HTTP 406 error status instead.

  • 对于带有 content-type: application/jsoncontent-type: application/expo+json 的响应,公共响应头其他响应头 必须在响应头中发送,显现主体 必须在响应正文中发送。这种格式的响应不支持多个响应部分,因此不支持指令,并且当要提供的最新响应不是更新时,应该以 HTTP 406 错误状态进行响应。

    ¥For a response with content-type: application/json or content-type: application/expo+json, the common response headers and other response headers MUST be sent in the response headers and the manifest body MUST be sent in the response body. This format of response does not support multiple response parts and therefore does not support directives, and SHOULD respond with an HTTP 406 error status when the most recent response to be served is not an update.

  • 对于 content-type: multipart/mixed 的响应,响应的结构必须按照 多部分响应 部分的规定。

    ¥For a response with content-type: multipart/mixed, the response MUST be structured as specified in the multipart response section.

  • 没有任何部分的 多部分响应 可以响应 HTTP 204 状态但没有内容,因此没有 content-type 响应头。

    ¥A multipart response with no parts MAY respond with an HTTP 204 status and no content, and thus no content-type response header.

更新和标头的选择取决于请求标头的值。符合要求的服务器必须以最新的更新进行响应,按创建时间排序,满足 请求标头 施加的所有参数和约束。服务器可以使用请求的任何属性(例如其标头和源 IP 地址)在全部满足请求约束的多个更新中进行选择。

¥The choice of update and headers are dependent on the values of the request headers. A conformant server MUST respond with the most recent update, ordered by creation time, satisfying all parameters and constraints imposed by the request headers. The server MAY use any properties of the request like its headers and source IP address to choose amongst several updates that all satisfy the request's constraints.

常见响应头

¥Common response headers

expo-protocol-version: 1
expo-sfv-version: 0
expo-manifest-filters: <expo-sfv>
expo-server-defined-headers: <expo-sfv>
cache-control: *
content-type: *
  • expo-protocol-version 描述了本规范中定义的协议版本,并且必须是 1

    ¥expo-protocol-version describes the version of the protocol defined in this spec and MUST be 1.

  • expo-sfv-version 必须是 0

    ¥expo-sfv-version MUST be 0.

  • expo-manifest-filtersExpo SFV 字典。它用于通过 manifest 中找到的 metadata 属性过滤客户端库存储的更新。如果过滤器中提到了某个字段,则元数据中的相应字段必须缺失或等于才能包含更新。客户端库必须存储清单过滤器,直到它被更新的响应覆盖。

    ¥expo-manifest-filters is an Expo SFV dictionary. It is used to filter updates stored by the client library by the metadata attribute found in the manifest. If a field is mentioned in the filter, the corresponding field in the metadata must either be missing or equal for the update to be included. The client library MUST store the manifest filters until it is overwritten by a newer response.

  • expo-server-defined-headersExpo SFV 字典。它定义了客户端库必须存储的标头,直到被较新的字典覆盖为止,并且它们必须包含在每个后续的 更新请求 中。

    ¥expo-server-defined-headers is an Expo SFV dictionary. It defines headers that a client library MUST store until overwritten by a newer dictionary, and they MUST be included in every subsequent update request.

  • cache-control 必须设置为适当短的时间段。建议使用值 cache-control: private, max-age=0 以确保返回最新的清单。设置较长的缓存期限可能会导致更新过时。

    ¥cache-control MUST be set to an appropriately short period of time. A value of cache-control: private, max-age=0 is recommended to ensure the newest manifest is returned. Setting longer cache ages could result in stale updates.

  • content-type 必须通过 RFC 7231 中定义的主动协商来确定。由于客户端库是 required 来随每个清单请求发送 accept 标头,因此这将始终是 application/expo+jsonapplication/json;否则请求将返回 406 错误。

    ¥content-type MUST be determined by proactive negotiation as defined in RFC 7231. Since the client library is required to send an accept header with each manifest request, this will always be either application/expo+json, application/json; otherwise the request would return a 406 error.

其他响应头

¥Other response headers

expo-signature: *
  • 如果清单请求包含 expo-expect-signature 标头,则 expo-signature 应包含在 代码签名 验证步骤期间使用的清单签名。这是一个 Expo SFV 字典,可以包含以下任何键值对:

    ¥expo-signature SHOULD contain the signature of the manifest to be used during the validation step of code signing if the request for the manifest contained the expo-expect-signature header. This is an Expo SFV dictionary which MAY contain any of the following key value pairs:

    • sig 必须包含清单的签名。该字段的名称与 expo-expect-signature 的名称相匹配。

      ¥sig MUST contain the signature of the manifest. The name of this field matches that of expo-expect-signature.

    • keyid 可以包含服务器用于签署响应的密钥的 keyId。客户端应该使用与该 keyid 匹配的证书来验证签名。

      ¥keyid MAY contain the keyId of the key the server used to sign the response. The client SHOULD use the certificate that matches this keyid to verify the signature.

    • alg 可以包含服务器用于签署响应的算法。仅当该字段与为匹配 keyid 的证书定义的算法匹配时,客户端才应使用该字段。

      ¥alg MAY contain the algorithm the server used to sign the response. The client SHOULD use this field only if it matches the algorithm defined for the certificate matching keyid.

多部分响应

¥Multipart response

此格式的更新响应由 RFC 2046 定义的 multipart/mixed MIME 类型定义。

¥An update response of this format is defined by the multipart/mixed MIME type as defined by RFC 2046.

此响应格式的标头为 公共响应头,但以下情况除外:

¥Headers for this response format are the common response headers, with the following exceptions:

  • content-type 应具有 RFC 2046 定义的 multipart/mixed

    ¥content-type SHOULD have a multipart/mixed value as defined by RFC 2046

零件顺序不严格。没有任何部分(零长度主体)的多部分响应应被视为无操作(没有可用的更新或指令),尽管响应的标头仍应发送并由客户端处理。

¥Part order is not strict. A multipart response with no parts (zero-length body) should be considered a no-op (no updates or directives available), though headers for the response SHOULD be sent nevertheless and processed by the client.

各部分定义如下:

¥Each part is defined as follows:

  1. 可选的 "manifest" 部分:

    ¥OPTIONAL "manifest" part:

    • 必须有零件标题 content-disposition: form-data; name="manifest"。第一个参数 (form-data) 不需要是 form-data,但 name 参数必须具有 manifest 作为值。

      ¥MUST have part header content-disposition: form-data; name="manifest". The first parameter (form-data) does not need to be form-data, but the name parameter must have manifest as a value.

    • 必须有零件标头 content-type: application/jsonapplication/expo+json

      ¥MUST have part header content-type: application/json or application/expo+json.

    • 如果使用代码签名,则应具有 其他响应头 中定义的部分标头 expo-signature

      ¥SHOULD have part header expo-signature as defined in other response headers if code signing is being used.

    • 显现主体 必须在零件正文中发送。

      ¥The manifest body MUST be sent in the part body.

  2. 可选的 "extensions" 部分:

    ¥OPTIONAL "extensions" part:

    • 必须有零件标题 content-disposition: form-data; name="extensions"。第一个参数 (form-data) 不需要是 form-data,但 name 参数必须具有 extensions 作为值。

      ¥MUST have part header content-disposition: form-data; name="extensions". The first parameter (form-data) does not need to be form-data, but the name parameter must have extensions as a value.

    • 必须有零件标题 content-type: application/json

      ¥MUST have part header content-type: application/json.

    • extensions-body 必须在零件正文中发送。

      ¥The extensions-body MUST be sent in the part body.

  3. 可选的 "directive" 部分:

    ¥OPTIONAL "directive" part:

    • 必须有零件标题 content-disposition: form-data; name="directive"。第一个参数 (form-data) 不需要是 form-data,但 name 参数必须具有 directive 作为值。

      ¥MUST have part header content-disposition: form-data; name="directive". The first parameter (form-data) does not need to be form-data, but the name parameter must have directive as a value.

    • 必须有零件标头 content-type: application/jsonapplication/expo+json

      ¥MUST have part header content-type: application/json or application/expo+json.

    • 如果使用代码签名,则应具有 其他响应头 中定义的部分标头 expo-signature

      ¥SHOULD have part header expo-signature as defined in other response headers if code signing is being used.

    • 指导机构 必须在零件正文中发送。

      ¥The directive body MUST be sent in the part body.

清单主体

¥Manifest body

定义为 JSON,同时符合以下 TypeScript 中表达的 Manifest 定义以及每个字段的详细描述:

¥Defined as JSON conforming to both the following Manifest definition expressed in TypeScript and the detailed descriptions for each field:

type Manifest = {
  id: string;
  createdAt: string;
  runtimeVersion: string;
  launchAsset: Asset;
  assets: Asset[];
  metadata: { [key: string]: string };
  extra: { [key: string]: any };
};

type Asset = {
  hash?: string;
  key: string;
  contentType: string;
  fileExtension?: string;
  url: string;
};
  • id:ID 必须唯一地指定清单,并且必须是 UUID。

    ¥id: The ID MUST uniquely specify the manifest and MUST be a UUID.

  • createdAt:创建更新的日期和时间至关重要,因为客户端库选择最新更新(受 expo-manifest-filters 标头提供的任何约束的约束)。日期时间应根据 ISO 8601 进行格式化。

    ¥createdAt: The date and time at which the update was created is essential as the client library selects the most recent update (subject to any constraints supplied by the expo-manifest-filters header). The datetime should be formatted according to ISO 8601.

  • runtimeVersion:可以是开发者定义的任何字符串。它规定了运行相关更新所需的原生代码设置。

    ¥runtimeVersion: Can be any string defined by the developer. It stipulates what native code setup is required to run the associated update.

  • launchAsset:一种特殊资源,是应用代码的入口点。该资源的 fileExtension 字段将被忽略,并且应该被省略。

    ¥launchAsset: A special asset that is the entry point of the application code. The fileExtension field will be ignored for this asset and SHOULD be omitted.

  • assets:更新包使用的一组资源,例如 JavaScript、图片和字体。在执行更新之前,应将所有资源(包括 launchAsset)下载到磁盘,并且应向应用代码提供资源 key 到磁盘上位置的映射。

    ¥assets: An array of assets used by the update bundle, such as JavaScript, pictures, and fonts. All assets (including the launchAsset) should be downloaded to disk before executing the update, and a mapping of asset keys to locations on disk should be provided to application code.

  • 每个资源对象的属性:

    ¥Properties of each asset object:

    • hash:文件的 Base64URL 编码 SHA-256 哈希可保证完整性。Base64URL 编码由 IETF RFC 4648 定义。

      ¥hash: Base64URL-encoded SHA-256 hash of the file to guarantee integrity. Base64URL encoding is defined by IETF RFC 4648.

    • key:用于从更新的应用代码引用此资源的密钥。例如,该密钥可以由处理应用代码的单独构建步骤(例如打包器)生成。

      ¥key: Key used to reference this asset from the update's application code. This key, for example, may be generated by a separate build step that processes the application code, such as a bundler.

    • contentTypeRFC 2045 定义的文件的 MIME 类型。例如,application/javascriptimage/jpeg

      ¥contentType: The MIME type of the file as defined by RFC 2045. For example, application/javascript, image/jpeg.

    • fileExtension:在客户端上保存文件时建议使用的扩展名。某些平台(例如 iOS)要求使用扩展名保存某些文件类型。扩展名必须以 . 为前缀。例如,.jpeg。 在某些情况下,例如 launchAsset,该字段将被忽略,以支持本地确定的扩展。如果省略该字段并且没有本地规定的扩展名,则资源将在没有扩展名的情况下保存。例如,./filename 末尾没有 .。如果文件扩展名不为空且缺少 . 前缀,则符合要求的客户端应该在文件扩展名前添加 . 前缀。

      ¥fileExtension: The suggested extension to use when a file is saved on a client. Some platforms, such as iOS, require certain file types to be saved with an extension. The extension MUST be prefixed with a .. For example, .jpeg. In some cases, such as the launchAsset, this field will be ignored in favor of a locally determined extension. If the field is omitted and there is no locally stipulated extension, the asset will be saved without an extension. For example, ./filename with no . at the end. A conforming client SHOULD prefix a file extension with a . if a file extension is not empty and missing the . prefix.

    • url:可以获取文件的位置。

      ¥url: Location at which the file may be fetched.

  • metadata:与更新关联的元数据。它是一个字符串值字典。服务器可以发回任何它希望用于过滤更新的内容。元数据必须通过随附的 expo-manifest-filters 标头中定义的过滤器。

    ¥metadata: The metadata associated with an update. It is a string-valued dictionary. The server MAY send back anything it wishes to be used for filtering the updates. The metadata MUST pass the filter defined in the accompanying expo-manifest-filters header.

  • extra:用于存储可选的 "extra" 信息,例如第三方配置。例如,如果更新托管在 Expo 应用服务 (EAS) 上,则可能会包含 EAS 项目 ID:

    ¥extra: For storage of optional "extra" information such as third-party configuration. For example, if the update is hosted on Expo Application Services (EAS), the EAS project ID may be included:

    "extra": {
      "eas": {
        "projectId": "00000000-0000-0000-0000-000000000000"
      }
    }
    

扩展主体

¥Extensions body

定义为 JSON,同时符合以下 TypeScript 中表达的 Extensions 定义以及每个字段的详细描述:

¥Defined as JSON conforming to both the following Extensions definition expressed in TypeScript and the detailed descriptions for each field:

type Extensions = {
  assetRequestHeaders: ExpoAssetHeaderDictionary;
  ...
}

type ExpoAssetHeaderDictionary = {
  [assetKey: string]: {
    [headerName: string]: string,
  };
}
  • assetRequestHeaders:可以包含标头(键,值)对的字典以包含在资源请求中。键和值必须都是字符串。

    ¥assetRequestHeaders: MAY contain a dictionary of header (key, value) pairs to include with asset requests. Key and value MUST both be strings.

指令体

¥Directive body

定义为 JSON,同时符合以下 TypeScript 中表达的 Directive 定义以及每个字段的详细描述:

¥Defined as JSON conforming to both the following Directive definition expressed in TypeScript and the detailed descriptions for each field:

type Directive = {
  type: string;
  parameters?: { [key: string]: any };
  extra?: { [key: string]: any };
};
  • type:指令的类型。

    ¥type: The type of directive.

  • parameters:可能包含特定于 type 的任何额外信息。

    ¥parameters: MAY contain any extra information specific to the type.

  • extra:用于存储可选的 "extra" 信息,例如第三方信息。例如,如果更新托管在 Expo 应用服务 (EAS) 上,则可能会包含 EAS 项目 ID。

    ¥extra: For storage of optional "extra" information such as third-party information. For example, if the update is hosted on Expo Application Services (EAS), the EAS project ID may be included.

一致的客户端库和服务器可以指定并实现特定于应用需求的指令类型。例如,Expo 应用服务迄今为止使用一种类型 rollBackToEmbedded,它指示 expo-updates 库使用嵌入在主机应用中的更新,而不是任何其他下载的更新。

¥A conformant client library and server MAY specify and implement directive types specific to the needs of the application. For example, Expo Application Services makes use of one type thus far, rollBackToEmbedded, which directs the expo-updates library to use the update embedded in the host application instead of any other downloaded updates.

资源请求

¥Asset request

符合要求的客户端库必须向清单指定的资源 URL 发出 GET 请求。客户端库应该包含一个标头,该标头接受清单中指定的资源内容类型。此外,客户端库应该指定客户端库能够处理的压缩编码。

¥A conformant client library MUST make a GET request to the asset URLs specified by the manifest. The client library SHOULD include a header accepting the asset's content type as specified in the manifest. Additionally, the client library SHOULD specify the compression encoding the client library is capable of handling.

标题示例:

¥Example headers:

accept: image/jpeg, */*
accept-encoding: br, gzip

一致的客户端库还必须包含 assetRequestHeaders 中包含的该资源密钥的任何标头(键、值)对。

¥A conformant client library MUST also include any header (key, value) pairs included in assetRequestHeaders for this asset key.

资源响应

¥Asset response

位于特定 URL 的资源不得更改或删除,因为客户端库可能随时获取资源以进行任何更新。符合要求的客户端必须验证资源的 base64url 编码的 SHA-256 哈希是否与清单中资源的 hash 字段匹配。

¥An asset located at a particular URL MUST NOT be changed or removed since client libraries may fetch assets for any update at any time. A conformant client MUST verify that the base64url-encoded SHA-256 hash of the asset matches the hash field for the asset from the manifest.

资源响应标头

¥Asset response headers

资源必须根据请求的 accept-encoding 标头使用客户端支持的压缩格式进行编码。服务器可以提供未压缩的资源。响应必须包含带有资源 MIME 类型的 content-type 标头。例如:

¥The asset MUST be encoded using a compression format that the client supports according to the request's accept-encoding header. The server MAY serve uncompressed assets. The response MUST include a content-type header with the MIME type of the asset. For example:

content-encoding: br
content-type: application/javascript

建议为资源提供设置为较长持续时间的 cache-control 标头,因为位于给定 URL 的资源不得更改。例如:

¥An asset is RECOMMENDED to be served with a cache-control header set to a long duration as an asset located at a given URL must not change. For example:

cache-control: public, max-age=31536000, immutable

压缩

¥Compression

资源应该能够通过 压缩包Brotli 压缩来提供服务。

¥Assets SHOULD be capable of being served with Gzip and Brotli compression.

代码签名

¥Code signing

Expo Updates 支持对清单和指令体进行代码签名。对清单进行代码签名也会对资源进行传递签名,因为它们的哈希值存在于清单中并由符合要求的客户端进行验证。符合要求的客户端可以请求使用私钥对清单或指令进行签名,然后必须在使用清单或指令或下载任何相应的清单资源之前使用相应的代码签名证书验证清单或指令的签名。客户端必须验证签名证书是自签名的受信任根证书,还是位于由受信任根证书签名的证书链中。在任何一种情况下,根证书都必须嵌入到应用或设备的操作系统中。

¥Expo Updates supports code signing the manifest and directive bodies. Code signing the manifest also transitively signs the assets since their hashes are present in the manifest and verified by a conformant client. A conformant client MAY request the manifest or directive be signed using a private key, and then MUST verify the signature of the manifest or directive using the corresponding code signing certificate before it is used or any corresponding manifest assets are downloaded. The client MUST verify that the signing certificate is either a self-signed, trusted root certificate or is in a certificate chain signed by a trusted root certificate. In either case, the root certificate MUST be embedded in the application or device's operating system.

Expo 中文网 - 粤ICP备13048890号